comparison libtomcrypt/src/ciphers/rc6.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
3 * LibTomCrypt is a library that provides various cryptographic 3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtom.org
10 */ 8 */
11 9
12 /** 10 /**
13 @file rc6.c 11 @file rc6.c
14 LTC_RC6 code by Tom St Denis 12 LTC_RC6 code by Tom St Denis
15 */ 13 */
16 #include "tomcrypt.h" 14 #include "tomcrypt.h"
17 15
18 #ifdef LTC_RC6 16 #ifdef LTC_RC6
19 17
26 &rc6_ecb_encrypt, 24 &rc6_ecb_encrypt,
27 &rc6_ecb_decrypt, 25 &rc6_ecb_decrypt,
28 &rc6_test, 26 &rc6_test,
29 &rc6_done, 27 &rc6_done,
30 &rc6_keysize, 28 &rc6_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 }; 30 };
33 31
34 static const ulong32 stab[44] = { 32 static const ulong32 stab[44] = {
35 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, 33 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
36 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, 34 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
57 55
58 LTC_ARGCHK(key != NULL); 56 LTC_ARGCHK(key != NULL);
59 LTC_ARGCHK(skey != NULL); 57 LTC_ARGCHK(skey != NULL);
60 58
61 /* test parameters */ 59 /* test parameters */
62 if (num_rounds != 0 && num_rounds != 20) { 60 if (num_rounds != 0 && num_rounds != 20) {
63 return CRYPT_INVALID_ROUNDS; 61 return CRYPT_INVALID_ROUNDS;
64 } 62 }
65 63
66 /* key must be between 64 and 1024 bits */ 64 /* key must be between 64 and 1024 bits */
67 if (keylen < 8 || keylen > 128) { 65 if (keylen < 8 || keylen > 128) {
68 return CRYPT_INVALID_KEYSIZE; 66 return CRYPT_INVALID_KEYSIZE;
69 } 67 }
70 68
71 /* copy the key into the L array */ 69 /* copy the key into the L array */
72 for (A = i = j = 0; i < (ulong32)keylen; ) { 70 for (A = i = j = 0; i < (ulong32)keylen; ) {
73 A = (A << 8) | ((ulong32)(key[i++] & 255)); 71 A = (A << 8) | ((ulong32)(key[i++] & 255));
74 if (!(i & 3)) { 72 if (!(i & 3)) {
75 L[j++] = BSWAP(A); 73 L[j++] = BSWAP(A);
76 A = 0; 74 A = 0;
77 } 75 }
78 } 76 }
79 77
80 /* handle odd sized keys */ 78 /* handle odd sized keys */
81 if (keylen & 3) { 79 if (keylen & 3) {
82 A <<= (8 * (4 - (keylen&3))); 80 A <<= (8 * (4 - (keylen&3)));
83 L[j++] = BSWAP(A); 81 L[j++] = BSWAP(A);
84 } 82 }
85 83
86 /* setup the S array */ 84 /* setup the S array */
87 XMEMCPY(S, stab, 44 * sizeof(stab[0])); 85 XMEMCPY(S, stab, 44 * sizeof(stab[0]));
88 86
89 /* mix buffer */ 87 /* mix buffer */
90 s = 3 * MAX(44, j); 88 s = 3 * MAX(44, j);
91 l = j; 89 l = j;
92 for (A = B = i = j = v = 0; v < s; v++) { 90 for (A = B = i = j = v = 0; v < s; v++) {
93 A = S[i] = ROLc(S[i] + A + B, 3); 91 A = S[i] = ROLc(S[i] + A + B, 3);
94 B = L[j] = ROL(L[j] + A + B, (A+B)); 92 B = L[j] = ROL(L[j] + A + B, (A+B));
95 if (++i == 44) { i = 0; } 93 if (++i == 44) { i = 0; }
96 if (++j == l) { j = 0; } 94 if (++j == l) { j = 0; }
97 } 95 }
98 96
99 /* copy to key */ 97 /* copy to key */
100 for (i = 0; i < 44; i++) { 98 for (i = 0; i < 44; i++) {
101 skey->rc6.K[i] = S[i]; 99 skey->rc6.K[i] = S[i];
102 } 100 }
103 return CRYPT_OK; 101 return CRYPT_OK;
104 } 102 }
105 103
125 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 123 int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
126 #endif 124 #endif
127 { 125 {
128 ulong32 a,b,c,d,t,u, *K; 126 ulong32 a,b,c,d,t,u, *K;
129 int r; 127 int r;
130 128
131 LTC_ARGCHK(skey != NULL); 129 LTC_ARGCHK(skey != NULL);
132 LTC_ARGCHK(pt != NULL); 130 LTC_ARGCHK(pt != NULL);
133 LTC_ARGCHK(ct != NULL); 131 LTC_ARGCHK(ct != NULL);
134 LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]); 132 LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]);
135 133
138 136
139 #define RND(a,b,c,d) \ 137 #define RND(a,b,c,d) \
140 t = (b * (b + b + 1)); t = ROLc(t, 5); \ 138 t = (b * (b + b + 1)); t = ROLc(t, 5); \
141 u = (d * (d + d + 1)); u = ROLc(u, 5); \ 139 u = (d * (d + d + 1)); u = ROLc(u, 5); \
142 a = ROL(a^t,u) + K[0]; \ 140 a = ROL(a^t,u) + K[0]; \
143 c = ROL(c^u,t) + K[1]; K += 2; 141 c = ROL(c^u,t) + K[1]; K += 2;
144 142
145 K = skey->rc6.K + 2; 143 K = skey->rc6.K + 2;
146 for (r = 0; r < 20; r += 4) { 144 for (r = 0; r < 20; r += 4) {
147 RND(a,b,c,d); 145 RND(a,b,c,d);
148 RND(b,c,d,a); 146 RND(b,c,d,a);
149 RND(c,d,a,b); 147 RND(c,d,a,b);
150 RND(d,a,b,c); 148 RND(d,a,b,c);
151 } 149 }
152 150
153 #undef RND 151 #undef RND
154 152
155 a += skey->rc6.K[42]; 153 a += skey->rc6.K[42];
156 c += skey->rc6.K[43]; 154 c += skey->rc6.K[43];
157 STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); 155 STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
169 167
170 /** 168 /**
171 Decrypts a block of text with LTC_RC6 169 Decrypts a block of text with LTC_RC6
172 @param ct The input ciphertext (16 bytes) 170 @param ct The input ciphertext (16 bytes)
173 @param pt The output plaintext (16 bytes) 171 @param pt The output plaintext (16 bytes)
174 @param skey The key as scheduled 172 @param skey The key as scheduled
175 */ 173 */
176 #ifdef LTC_CLEAN_STACK 174 #ifdef LTC_CLEAN_STACK
177 static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 175 static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
178 #else 176 #else
179 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 177 int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
183 int r; 181 int r;
184 182
185 LTC_ARGCHK(skey != NULL); 183 LTC_ARGCHK(skey != NULL);
186 LTC_ARGCHK(pt != NULL); 184 LTC_ARGCHK(pt != NULL);
187 LTC_ARGCHK(ct != NULL); 185 LTC_ARGCHK(ct != NULL);
188 186
189 LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]); 187 LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]);
190 a -= skey->rc6.K[42]; 188 a -= skey->rc6.K[42];
191 c -= skey->rc6.K[43]; 189 c -= skey->rc6.K[43];
192 190
193 #define RND(a,b,c,d) \ 191 #define RND(a,b,c,d) \
194 t = (b * (b + b + 1)); t = ROLc(t, 5); \ 192 t = (b * (b + b + 1)); t = ROLc(t, 5); \
195 u = (d * (d + d + 1)); u = ROLc(u, 5); \ 193 u = (d * (d + d + 1)); u = ROLc(u, 5); \
196 c = ROR(c - K[1], t) ^ u; \ 194 c = ROR(c - K[1], t) ^ u; \
197 a = ROR(a - K[0], u) ^ t; K -= 2; 195 a = ROR(a - K[0], u) ^ t; K -= 2;
198 196
199 K = skey->rc6.K + 40; 197 K = skey->rc6.K + 40;
200 198
201 for (r = 0; r < 20; r += 4) { 199 for (r = 0; r < 20; r += 4) {
202 RND(d,a,b,c); 200 RND(d,a,b,c);
203 RND(c,d,a,b); 201 RND(c,d,a,b);
204 RND(b,c,d,a); 202 RND(b,c,d,a);
205 RND(a,b,c,d); 203 RND(a,b,c,d);
206 } 204 }
207 205
208 #undef RND 206 #undef RND
209 207
210 b -= skey->rc6.K[0]; 208 b -= skey->rc6.K[0];
211 d -= skey->rc6.K[1]; 209 d -= skey->rc6.K[1];
212 STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); 210 STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
229 */ 227 */
230 int rc6_test(void) 228 int rc6_test(void)
231 { 229 {
232 #ifndef LTC_TEST 230 #ifndef LTC_TEST
233 return CRYPT_NOP; 231 return CRYPT_NOP;
234 #else 232 #else
235 static const struct { 233 static const struct {
236 int keylen; 234 int keylen;
237 unsigned char key[32], pt[16], ct[16]; 235 unsigned char key[32], pt[16], ct[16];
238 } tests[] = { 236 } tests[] = {
239 { 237 {
283 /* encrypt and decrypt */ 281 /* encrypt and decrypt */
284 rc6_ecb_encrypt(tests[x].pt, tmp[0], &key); 282 rc6_ecb_encrypt(tests[x].pt, tmp[0], &key);
285 rc6_ecb_decrypt(tmp[0], tmp[1], &key); 283 rc6_ecb_decrypt(tmp[0], tmp[1], &key);
286 284
287 /* compare */ 285 /* compare */
288 if (XMEMCMP(tmp[0], tests[x].ct, 16) || XMEMCMP(tmp[1], tests[x].pt, 16)) { 286 if (compare_testvector(tmp[0], 16, tests[x].ct, 16, "RC6 Encrypt", x) ||
289 #if 0 287 compare_testvector(tmp[1], 16, tests[x].pt, 16, "RC6 Decrypt", x)) {
290 printf("\n\nFailed test %d\n", x);
291 if (XMEMCMP(tmp[0], tests[x].ct, 16)) {
292 printf("Ciphertext: ");
293 for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]);
294 printf("\nExpected : ");
295 for (y = 0; y < 16; y++) printf("%02x ", tests[x].ct[y]);
296 printf("\n");
297 }
298 if (XMEMCMP(tmp[1], tests[x].pt, 16)) {
299 printf("Plaintext: ");
300 for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]);
301 printf("\nExpected : ");
302 for (y = 0; y < 16; y++) printf("%02x ", tests[x].pt[y]);
303 printf("\n");
304 }
305 #endif
306 return CRYPT_FAIL_TESTVECTOR; 288 return CRYPT_FAIL_TESTVECTOR;
307 } 289 }
308 290
309 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ 291 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
310 for (y = 0; y < 16; y++) tmp[0][y] = 0; 292 for (y = 0; y < 16; y++) tmp[0][y] = 0;
314 } 296 }
315 return CRYPT_OK; 297 return CRYPT_OK;
316 #endif 298 #endif
317 } 299 }
318 300
319 /** Terminate the context 301 /** Terminate the context
320 @param skey The scheduled key 302 @param skey The scheduled key
321 */ 303 */
322 void rc6_done(symmetric_key *skey) 304 void rc6_done(symmetric_key *skey)
323 { 305 {
306 LTC_UNUSED_PARAM(skey);
324 } 307 }
325 308
326 /** 309 /**
327 Gets suitable key size 310 Gets suitable key size
328 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. 311 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
341 324
342 #endif /*LTC_RC6*/ 325 #endif /*LTC_RC6*/
343 326
344 327
345 328
346 /* $Source$ */ 329 /* ref: $Format:%D$ */
347 /* $Revision$ */ 330 /* git commit: $Format:%H$ */
348 /* $Date$ */ 331 /* commit time: $Format:%ai$ */