3 This file is part of the ARM-Crypto-Lib.
4 Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * a implementation of the PRESENT block-cipher
23 * email: daniel.otte@rub.de
32 static uint8_t sbox(uint8_t b){
33 const uint8_t sb[]={ 0xC, 0x5, 0x6, 0xB,
37 return (((sb[b>>4])<<4)|(sb[b&0xf]));
40 static uint8_t sbox_inv(uint8_t b){
41 const uint8_t sb[]={ 0x5, 0xE, 0xF, 0x8,
45 return (((sb[b>>4])<<4)|(sb[b&0xf]));
48 #define SHR_O(a) c=(a)&1; (a)>>=1;
49 #define SHR_I(a) (a)=(c?0x8000:0x0000) | ((a)>>1);
51 static void p(uint16_t* o, uint8_t* i){
68 static void p_inv(uint8_t* o, uint8_t* i){
74 void present_init(const uint8_t* key, uint8_t keysize_b, present_ctx_t* ctx){
76 union __attribute__((packed)) {
80 struct __attribute__((packed)) {
86 memcpy(b.v8, key, 10);
87 memcpy(&(ctx->k[0]), b.v8+2, 8);
89 /* rotate buffer 19 right */
91 memmove(b.v8, b.v8+2, 8);
92 memcpy(b.v8+8, tmp, 2);
93 /* three shifts to do*/
99 /* rotating done now substitution */
100 b.v8[9] = (sbox(b.v8[9])&0xF0) | ((b.v8[9])&0x0F);
101 /* xor with round counter */
102 b.off1.v16[0] ^= (uint16_t)i<<7;
103 memcpy(&(ctx->k[i]), b.v8+2, 8);
107 void present_enc(void* buffer, present_ctx_t* ctx){
110 *((uint64_t*)buffer) ^= ctx->k[i];
112 tmp[j] = sbox(((uint8_t*)buffer)[j]);
114 p((uint16_t*)buffer, tmp);
116 *((uint64_t*)buffer) ^= ctx->k[31];
120 void present_dec(void* buffer, present_ctx_t* ctx){
123 *((uint64_t*)buffer) ^= ctx->k[31];
125 for(i=30; i>=0; --i){
126 p_inv(tmp, (uint8_t*)buffer);
128 ((uint8_t*)buffer)[j] = sbox_inv(tmp[j]);
130 *((uint64_t*)buffer) ^= ctx->k[i];