Mercurial > dropbear
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$ */ |