merge master
Karel Miko
9 years ago
24 | 24 | ^Build$ |
25 | 25 | ^Build\.bat$ |
26 | 26 | ^MANIFEST\.SKIP$ |
27 | ^tmp* | |
27 | tmp.* | |
28 | 28 | ^poznamky* |
29 | 29 | \.stackdump$ |
30 | 30 | ^.travis* |
87 | 87 | |
88 | 88 | #endif |
89 | 89 | |
90 | #define __LTC_AES_TAB_C__ | |
90 | 91 | #include "aes_tab.c.inc" |
91 | 92 | |
92 | 93 | static ulong32 setup_mix(ulong32 temp) |
119 | 120 | */ |
120 | 121 | int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) |
121 | 122 | { |
122 | int i, j; | |
123 | int i; | |
123 | 124 | ulong32 temp, *rk; |
124 | 125 | #ifndef ENCRYPT_ONLY |
125 | 126 | ulong32 *rrk; |
126 | #endif | |
127 | #endif | |
127 | 128 | LTC_ARGCHK(key != NULL); |
128 | 129 | LTC_ARGCHK(skey != NULL); |
129 | ||
130 | ||
130 | 131 | if (keylen != 16 && keylen != 24 && keylen != 32) { |
131 | 132 | return CRYPT_INVALID_KEYSIZE; |
132 | 133 | } |
133 | ||
134 | ||
134 | 135 | if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) { |
135 | 136 | return CRYPT_INVALID_ROUNDS; |
136 | 137 | } |
137 | ||
138 | ||
138 | 139 | skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; |
139 | ||
140 | ||
140 | 141 | /* setup the forward key */ |
141 | 142 | i = 0; |
142 | 143 | rk = skey->rijndael.eK; |
145 | 146 | LOAD32H(rk[2], key + 8); |
146 | 147 | LOAD32H(rk[3], key + 12); |
147 | 148 | if (keylen == 16) { |
148 | j = 44; | |
149 | 149 | for (;;) { |
150 | 150 | temp = rk[3]; |
151 | 151 | rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i]; |
158 | 158 | rk += 4; |
159 | 159 | } |
160 | 160 | } else if (keylen == 24) { |
161 | j = 52; | |
162 | 161 | LOAD32H(rk[4], key + 16); |
163 | 162 | LOAD32H(rk[5], key + 20); |
164 | 163 | for (;;) { |
165 | 164 | #ifdef _MSC_VER |
166 | temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; | |
165 | temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; | |
167 | 166 | #else |
168 | 167 | temp = rk[5]; |
169 | 168 | #endif |
179 | 178 | rk += 6; |
180 | 179 | } |
181 | 180 | } else if (keylen == 32) { |
182 | j = 60; | |
183 | 181 | LOAD32H(rk[4], key + 16); |
184 | 182 | LOAD32H(rk[5], key + 20); |
185 | 183 | LOAD32H(rk[6], key + 24); |
186 | 184 | LOAD32H(rk[7], key + 28); |
187 | 185 | for (;;) { |
188 | 186 | #ifdef _MSC_VER |
189 | temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; | |
187 | temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; | |
190 | 188 | #else |
191 | 189 | temp = rk[7]; |
192 | 190 | #endif |
209 | 207 | return CRYPT_ERROR; |
210 | 208 | } |
211 | 209 | |
212 | #ifndef ENCRYPT_ONLY | |
210 | #ifndef ENCRYPT_ONLY | |
213 | 211 | /* setup the inverse key now */ |
214 | 212 | rk = skey->rijndael.dK; |
215 | rrk = skey->rijndael.eK + j - 4; | |
216 | ||
213 | rrk = skey->rijndael.eK + (28 + keylen) - 4; | |
214 | ||
217 | 215 | /* apply the inverse MixColumn transform to all round keys but the first and the last: */ |
218 | 216 | /* copy first */ |
219 | 217 | *rk++ = *rrk++; |
221 | 219 | *rk++ = *rrk++; |
222 | 220 | *rk = *rrk; |
223 | 221 | rk -= 3; rrk -= 3; |
224 | ||
222 | ||
225 | 223 | for (i = 1; i < skey->rijndael.Nr; i++) { |
226 | 224 | rrk -= 4; |
227 | 225 | rk += 4; |
228 | #ifdef LTC_SMALL_CODE | |
226 | #ifdef LTC_SMALL_CODE | |
229 | 227 | temp = rrk[0]; |
230 | 228 | rk[0] = setup_mix2(temp); |
231 | 229 | temp = rrk[1]; |
259 | 257 | Tks1[byte(temp, 2)] ^ |
260 | 258 | Tks2[byte(temp, 1)] ^ |
261 | 259 | Tks3[byte(temp, 0)]; |
262 | #endif | |
263 | ||
260 | #endif | |
261 | ||
264 | 262 | } |
265 | 263 | |
266 | 264 | /* copy last */ |
272 | 270 | *rk = *rrk; |
273 | 271 | #endif /* ENCRYPT_ONLY */ |
274 | 272 | |
275 | return CRYPT_OK; | |
273 | return CRYPT_OK; | |
276 | 274 | } |
277 | 275 | |
278 | 276 | /** |
283 | 281 | @return CRYPT_OK if successful |
284 | 282 | */ |
285 | 283 | #ifdef LTC_CLEAN_STACK |
286 | static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
284 | static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
287 | 285 | #else |
288 | 286 | int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) |
289 | 287 | #endif |
290 | 288 | { |
291 | 289 | ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; |
292 | 290 | int Nr, r; |
293 | ||
291 | ||
294 | 292 | LTC_ARGCHK(pt != NULL); |
295 | 293 | LTC_ARGCHK(ct != NULL); |
296 | 294 | LTC_ARGCHK(skey != NULL); |
297 | ||
295 | ||
298 | 296 | Nr = skey->rijndael.Nr; |
299 | 297 | rk = skey->rijndael.eK; |
300 | ||
298 | ||
301 | 299 | /* |
302 | 300 | * map byte array block to cipher state |
303 | 301 | * and add initial round key: |
335 | 333 | Te2(byte(s1, 1)) ^ |
336 | 334 | Te3(byte(s2, 0)) ^ |
337 | 335 | rk[3]; |
338 | if (r == Nr-2) { | |
336 | if (r == Nr-2) { | |
339 | 337 | break; |
340 | 338 | } |
341 | 339 | s0 = t0; s1 = t1; s2 = t2; s3 = t3; |
436 | 434 | (Te4_3[byte(t3, 3)]) ^ |
437 | 435 | (Te4_2[byte(t0, 2)]) ^ |
438 | 436 | (Te4_1[byte(t1, 1)]) ^ |
439 | (Te4_0[byte(t2, 0)]) ^ | |
437 | (Te4_0[byte(t2, 0)]) ^ | |
440 | 438 | rk[3]; |
441 | 439 | STORE32H(s3, ct+12); |
442 | 440 | |
444 | 442 | } |
445 | 443 | |
446 | 444 | #ifdef LTC_CLEAN_STACK |
447 | int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
445 | int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
448 | 446 | { |
449 | 447 | int err = _rijndael_ecb_encrypt(pt, ct, skey); |
450 | 448 | burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); |
452 | 450 | } |
453 | 451 | #endif |
454 | 452 | |
455 | #ifndef ENCRYPT_ONLY | |
453 | #ifndef ENCRYPT_ONLY | |
456 | 454 | |
457 | 455 | /** |
458 | 456 | Decrypts a block of text with AES |
459 | 457 | @param ct The input ciphertext (16 bytes) |
460 | 458 | @param pt The output plaintext (16 bytes) |
461 | @param skey The key as scheduled | |
459 | @param skey The key as scheduled | |
462 | 460 | @return CRYPT_OK if successful |
463 | 461 | */ |
464 | 462 | #ifdef LTC_CLEAN_STACK |
465 | static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | |
463 | static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | |
466 | 464 | #else |
467 | 465 | int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) |
468 | 466 | #endif |
473 | 471 | LTC_ARGCHK(pt != NULL); |
474 | 472 | LTC_ARGCHK(ct != NULL); |
475 | 473 | LTC_ARGCHK(skey != NULL); |
476 | ||
474 | ||
477 | 475 | Nr = skey->rijndael.Nr; |
478 | 476 | rk = skey->rijndael.dK; |
479 | 477 | |
514 | 512 | Td3(byte(s0, 0)) ^ |
515 | 513 | rk[3]; |
516 | 514 | if (r == Nr-2) { |
517 | break; | |
515 | break; | |
518 | 516 | } |
519 | 517 | s0 = t0; s1 = t1; s2 = t2; s3 = t3; |
520 | 518 | } |
521 | 519 | rk += 4; |
522 | 520 | |
523 | #else | |
521 | #else | |
524 | 522 | |
525 | 523 | /* |
526 | 524 | * Nr - 1 full rounds: |
624 | 622 | |
625 | 623 | |
626 | 624 | #ifdef LTC_CLEAN_STACK |
627 | int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | |
625 | int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | |
628 | 626 | { |
629 | 627 | int err = _rijndael_ecb_decrypt(ct, pt, skey); |
630 | 628 | burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); |
640 | 638 | { |
641 | 639 | #ifndef LTC_TEST |
642 | 640 | return CRYPT_NOP; |
643 | #else | |
641 | #else | |
644 | 642 | int err; |
645 | 643 | static const struct { |
646 | 644 | int keylen; |
647 | 645 | unsigned char key[32], pt[16], ct[16]; |
648 | 646 | } tests[] = { |
649 | 647 | { 16, |
650 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
651 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, | |
648 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
649 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, | |
652 | 650 | { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, |
653 | 651 | 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, |
654 | { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, | |
652 | { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, | |
655 | 653 | 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } |
656 | }, { | |
654 | }, { | |
657 | 655 | 24, |
658 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
656 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
659 | 657 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
660 | 658 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, |
661 | 659 | { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, |
662 | 660 | 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, |
663 | { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, | |
661 | { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, | |
664 | 662 | 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } |
665 | 663 | }, { |
666 | 664 | 32, |
667 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
665 | { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
668 | 666 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
669 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | |
667 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | |
670 | 668 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, |
671 | 669 | { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, |
672 | 670 | 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, |
673 | { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, | |
671 | { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, | |
674 | 672 | 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } |
675 | 673 | } |
676 | 674 | }; |
677 | ||
675 | ||
678 | 676 | symmetric_key key; |
679 | 677 | unsigned char tmp[2][16]; |
680 | 678 | int i, y; |
681 | ||
679 | ||
682 | 680 | for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { |
683 | 681 | zeromem(&key, sizeof(key)); |
684 | if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { | |
682 | if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { | |
685 | 683 | return err; |
686 | 684 | } |
687 | ||
685 | ||
688 | 686 | rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); |
689 | 687 | rijndael_ecb_decrypt(tmp[0], tmp[1], &key); |
690 | if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { | |
688 | if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { | |
691 | 689 | #if 0 |
692 | 690 | printf("\n\nTest %d failed\n", i); |
693 | 691 | if (XMEMCMP(tmp[0], tests[i].ct, 16)) { |
703 | 701 | } |
704 | 702 | printf("\n"); |
705 | 703 | } |
706 | #endif | |
704 | #endif | |
707 | 705 | return CRYPT_FAIL_TESTVECTOR; |
708 | 706 | } |
709 | 707 | |
712 | 710 | for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); |
713 | 711 | for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); |
714 | 712 | for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; |
715 | } | |
713 | } | |
716 | 714 | return CRYPT_OK; |
717 | 715 | #endif |
718 | 716 | } |
720 | 718 | #endif /* ENCRYPT_ONLY */ |
721 | 719 | |
722 | 720 | |
723 | /** Terminate the context | |
721 | /** Terminate the context | |
724 | 722 | @param skey The scheduled key |
725 | 723 | */ |
726 | 724 | void ECB_DONE(symmetric_key *skey) |
31 | 31 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL |
32 | 32 | }; |
33 | 33 | |
34 | #define MIN_N 4 | |
35 | #define MAX_N 10 | |
36 | #define MIN_ROUNDS (8 + MIN_N) | |
37 | #define MAX_ROUNDS (8 + MAX_N) | |
38 | #define MIN_KEYSIZEB (4*MIN_N) | |
39 | #define MAX_KEYSIZEB (4*MAX_N) | |
40 | #define BLOCKSIZE 128 | |
41 | #define BLOCKSIZEB (BLOCKSIZE/8) | |
34 | #define MIN_N 4 | |
35 | #define MAX_N 10 | |
36 | #define MIN_ROUNDS (8 + MIN_N) | |
37 | #define MAX_ROUNDS (8 + MAX_N) | |
38 | #define MIN_KEYSIZEB (4*MIN_N) | |
39 | #define MAX_KEYSIZEB (4*MAX_N) | |
40 | #define BLOCKSIZE 128 | |
41 | #define BLOCKSIZEB (BLOCKSIZE/8) | |
42 | 42 | |
43 | 43 | |
44 | 44 | /* |
930 | 930 | */ |
931 | 931 | for (i = 0, pos = 0; i < N; i++, pos += 4) { |
932 | 932 | kappa[i] = |
933 | (key[pos ] << 24) ^ | |
934 | (key[pos + 1] << 16) ^ | |
935 | (key[pos + 2] << 8) ^ | |
936 | (key[pos + 3] ); | |
933 | (((ulong32)key[pos ]) << 24) ^ | |
934 | (((ulong32)key[pos + 1]) << 16) ^ | |
935 | (((ulong32)key[pos + 2]) << 8) ^ | |
936 | (((ulong32)key[pos + 3]) ); | |
937 | 937 | } |
938 | 938 | |
939 | 939 | /* |
1033 | 1033 | return err; |
1034 | 1034 | } |
1035 | 1035 | #endif |
1036 | ||
1036 | ||
1037 | 1037 | |
1038 | 1038 | static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext, |
1039 | 1039 | ulong32 roundKey[18 + 1][4], int R) { |
1047 | 1047 | */ |
1048 | 1048 | for (i = 0, pos = 0; i < 4; i++, pos += 4) { |
1049 | 1049 | state[i] = |
1050 | (plaintext[pos ] << 24) ^ | |
1051 | (plaintext[pos + 1] << 16) ^ | |
1052 | (plaintext[pos + 2] << 8) ^ | |
1053 | (plaintext[pos + 3] ) ^ | |
1050 | (((ulong32)plaintext[pos ]) << 24) ^ | |
1051 | (((ulong32)plaintext[pos + 1]) << 16) ^ | |
1052 | (((ulong32)plaintext[pos + 2]) << 8) ^ | |
1053 | (((ulong32)plaintext[pos + 3]) ) ^ | |
1054 | 1054 | roundKey[0][i]; |
1055 | 1055 | } |
1056 | 1056 | |
1148 | 1148 | Decrypts a block of text with Anubis |
1149 | 1149 | @param ct The input ciphertext (16 bytes) |
1150 | 1150 | @param pt The output plaintext (16 bytes) |
1151 | @param skey The key as scheduled | |
1151 | @param skey The key as scheduled | |
1152 | 1152 | @return CRYPT_OK if successful |
1153 | 1153 | */ |
1154 | 1154 | int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) |
1180 | 1180 | 16, |
1181 | 1181 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1182 | 1182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1183 | { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18, | |
1183 | { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18, | |
1184 | 1184 | 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE }, |
1185 | 1185 | { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1186 | 1186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } |
1188 | 1188 | 16, |
1189 | 1189 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1190 | 1190 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1191 | { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89, | |
1191 | { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89, | |
1192 | 1192 | 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D }, |
1193 | 1193 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1194 | 1194 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } |
1220 | 1220 | 24, |
1221 | 1221 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1222 | 1222 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1223 | { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66, | |
1223 | { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66, | |
1224 | 1224 | 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 }, |
1225 | 1225 | { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1226 | 1226 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1229 | 1229 | 24, |
1230 | 1230 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1231 | 1231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1232 | { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD, | |
1232 | { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD, | |
1233 | 1233 | 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 }, |
1234 | 1234 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1235 | 1235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1241 | 1241 | 28, |
1242 | 1242 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1243 | 1243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1244 | { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B, | |
1244 | { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B, | |
1245 | 1245 | 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 }, |
1246 | 1246 | { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1247 | 1247 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1251 | 1251 | 28, |
1252 | 1252 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1253 | 1253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1254 | { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53, | |
1254 | { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53, | |
1255 | 1255 | 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F }, |
1256 | 1256 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1257 | 1257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1264 | 1264 | 32, |
1265 | 1265 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1266 | 1266 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1267 | { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13, | |
1267 | { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13, | |
1268 | 1268 | 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 }, |
1269 | 1269 | { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1270 | 1270 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1274 | 1274 | 32, |
1275 | 1275 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1276 | 1276 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1277 | { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29, | |
1277 | { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29, | |
1278 | 1278 | 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 }, |
1279 | 1279 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1280 | 1280 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1287 | 1287 | 36, |
1288 | 1288 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1289 | 1289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1290 | { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B, | |
1290 | { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B, | |
1291 | 1291 | 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C }, |
1292 | 1292 | { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1293 | 1293 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1298 | 1298 | 36, |
1299 | 1299 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1300 | 1300 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1301 | { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2, | |
1301 | { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2, | |
1302 | 1302 | 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 }, |
1303 | 1303 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1304 | 1304 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1312 | 1312 | 40, |
1313 | 1313 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1314 | 1314 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1315 | { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02, | |
1315 | { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02, | |
1316 | 1316 | 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 }, |
1317 | 1317 | { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1318 | 1318 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1323 | 1323 | 40, |
1324 | 1324 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1325 | 1325 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
1326 | { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0, | |
1326 | { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0, | |
1327 | 1327 | 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 }, |
1328 | 1328 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1329 | 1329 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
1514 | 1514 | #endif |
1515 | 1515 | } |
1516 | 1516 | |
1517 | /** Terminate the context | |
1517 | /** Terminate the context | |
1518 | 1518 | @param skey The scheduled key |
1519 | 1519 | */ |
1520 | 1520 | void anubis_done(symmetric_key *skey) |
31 | 31 | }; |
32 | 32 | |
33 | 33 | static const ulong32 SP1110[] = { |
34 | 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500, | |
35 | 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, | |
36 | 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, | |
37 | 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00, | |
38 | 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, | |
39 | 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, | |
40 | 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00, | |
41 | 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, | |
42 | 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, | |
43 | 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900, | |
44 | 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, | |
45 | 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, | |
46 | 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00, | |
47 | 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, | |
48 | 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, | |
49 | 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000, | |
50 | 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, | |
51 | 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, | |
52 | 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00, | |
53 | 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, | |
54 | 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, | |
55 | 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200, | |
56 | 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, | |
57 | 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, | |
58 | 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00, | |
59 | 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, | |
60 | 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, | |
61 | 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00, | |
62 | 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, | |
63 | 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, | |
64 | 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100, | |
65 | 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00, | |
34 | 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500, | |
35 | 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, | |
36 | 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, | |
37 | 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00, | |
38 | 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, | |
39 | 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, | |
40 | 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00, | |
41 | 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, | |
42 | 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, | |
43 | 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900, | |
44 | 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, | |
45 | 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, | |
46 | 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00, | |
47 | 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, | |
48 | 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, | |
49 | 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000, | |
50 | 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, | |
51 | 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, | |
52 | 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00, | |
53 | 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, | |
54 | 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, | |
55 | 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200, | |
56 | 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, | |
57 | 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, | |
58 | 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00, | |
59 | 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, | |
60 | 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, | |
61 | 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00, | |
62 | 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, | |
63 | 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, | |
64 | 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100, | |
65 | 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00, | |
66 | 66 | }; |
67 | 67 | |
68 | 68 | static const ulong32 SP0222[] = { |
69 | 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb, | |
70 | 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, | |
71 | 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, | |
72 | 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b, | |
73 | 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, | |
74 | 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, | |
75 | 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a, | |
76 | 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, | |
77 | 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, | |
78 | 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333, | |
79 | 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, | |
80 | 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, | |
81 | 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838, | |
82 | 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, | |
83 | 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, | |
84 | 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0, | |
85 | 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, | |
86 | 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, | |
87 | 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7, | |
88 | 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, | |
89 | 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, | |
90 | 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5, | |
91 | 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, | |
92 | 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, | |
93 | 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d, | |
94 | 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, | |
95 | 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, | |
96 | 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5, | |
97 | 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, | |
98 | 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, | |
99 | 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383, | |
100 | 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d, | |
69 | 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb, | |
70 | 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, | |
71 | 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, | |
72 | 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b, | |
73 | 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, | |
74 | 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, | |
75 | 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a, | |
76 | 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, | |
77 | 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, | |
78 | 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333, | |
79 | 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, | |
80 | 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, | |
81 | 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838, | |
82 | 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, | |
83 | 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, | |
84 | 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0, | |
85 | 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, | |
86 | 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, | |
87 | 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7, | |
88 | 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, | |
89 | 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, | |
90 | 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5, | |
91 | 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, | |
92 | 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, | |
93 | 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d, | |
94 | 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, | |
95 | 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, | |
96 | 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5, | |
97 | 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, | |
98 | 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, | |
99 | 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383, | |
100 | 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d, | |
101 | 101 | }; |
102 | 102 | |
103 | 103 | static const ulong32 SP3033[] = { |
104 | 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2, | |
105 | 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, | |
106 | 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, | |
107 | 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede, | |
108 | 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, | |
109 | 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, | |
110 | 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e, | |
111 | 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, | |
112 | 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, | |
113 | 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc, | |
114 | 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, | |
115 | 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, | |
116 | 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e, | |
117 | 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, | |
118 | 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, | |
119 | 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828, | |
120 | 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, | |
121 | 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, | |
122 | 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded, | |
123 | 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, | |
124 | 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, | |
125 | 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171, | |
126 | 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, | |
127 | 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, | |
128 | 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747, | |
129 | 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, | |
130 | 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, | |
131 | 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d, | |
132 | 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, | |
133 | 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, | |
134 | 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0, | |
135 | 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f, | |
104 | 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2, | |
105 | 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, | |
106 | 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, | |
107 | 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede, | |
108 | 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, | |
109 | 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, | |
110 | 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e, | |
111 | 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, | |
112 | 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, | |
113 | 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc, | |
114 | 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, | |
115 | 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, | |
116 | 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e, | |
117 | 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, | |
118 | 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, | |
119 | 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828, | |
120 | 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, | |
121 | 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, | |
122 | 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded, | |
123 | 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, | |
124 | 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, | |
125 | 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171, | |
126 | 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, | |
127 | 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, | |
128 | 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747, | |
129 | 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, | |
130 | 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, | |
131 | 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d, | |
132 | 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, | |
133 | 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, | |
134 | 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0, | |
135 | 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f, | |
136 | 136 | }; |
137 | 137 | |
138 | 138 | static const ulong32 SP4404[] = { |
139 | 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae, | |
140 | 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, | |
141 | 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, | |
142 | 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c, | |
143 | 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, | |
144 | 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, | |
145 | 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2, | |
146 | 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, | |
147 | 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, | |
148 | 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd, | |
149 | 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, | |
150 | 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, | |
151 | 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4, | |
152 | 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, | |
153 | 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, | |
154 | 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080, | |
155 | 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, | |
156 | 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, | |
157 | 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a, | |
158 | 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, | |
159 | 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, | |
160 | 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7, | |
161 | 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, | |
162 | 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, | |
163 | 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2, | |
164 | 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, | |
165 | 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, | |
166 | 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e, | |
167 | 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, | |
168 | 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, | |
169 | 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4, | |
170 | 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e, | |
139 | 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae, | |
140 | 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, | |
141 | 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, | |
142 | 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c, | |
143 | 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, | |
144 | 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, | |
145 | 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2, | |
146 | 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, | |
147 | 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, | |
148 | 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd, | |
149 | 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, | |
150 | 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, | |
151 | 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4, | |
152 | 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, | |
153 | 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, | |
154 | 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080, | |
155 | 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, | |
156 | 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, | |
157 | 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a, | |
158 | 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, | |
159 | 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, | |
160 | 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7, | |
161 | 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, | |
162 | 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, | |
163 | 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2, | |
164 | 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, | |
165 | 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, | |
166 | 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e, | |
167 | 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, | |
168 | 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, | |
169 | 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4, | |
170 | 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e, | |
171 | 171 | }; |
172 | 172 | |
173 | 173 | static ulong64 key_sigma[] = { |
197 | 197 | static void rot_128(unsigned char *in, unsigned count, unsigned char *out) |
198 | 198 | { |
199 | 199 | unsigned x, w, b; |
200 | ||
201 | w = count >> 3; | |
200 | ||
201 | w = count >> 3; | |
202 | 202 | b = count & 7; |
203 | ||
203 | ||
204 | 204 | for (x = 0; x < 16; x++) { |
205 | 205 | out[x] = (in[(x+w)&15] << b) | (in[(x+w+1)&15] >> (8 - b)); |
206 | 206 | } |
211 | 211 | unsigned char T[48], kA[16], kB[16], kR[16], kL[16]; |
212 | 212 | int x; |
213 | 213 | ulong64 A, B; |
214 | ||
215 | /* | |
216 | LTC_ARGCHK(key != NULL); | |
217 | LTC_ARGCHK(skey != NULL); | |
218 | */ | |
214 | ||
215 | // LTC_ARGCHK(key != NULL); | |
216 | // LTC_ARGCHK(skey != NULL); | |
219 | 217 | |
220 | 218 | /* Valid sizes (in bytes) are 16, 24, 32 */ |
221 | 219 | if (keylen != 16 && keylen != 24 && keylen != 32) { |
228 | 226 | if (num_rounds != 0 && num_rounds != skey->camellia.R) { |
229 | 227 | return CRYPT_INVALID_ROUNDS; |
230 | 228 | } |
231 | ||
229 | ||
232 | 230 | /* expand key */ |
233 | 231 | if (keylen == 16) { |
234 | for (x = 0; x < 16; x++) { | |
235 | T[x] = key[x]; | |
232 | for (x = 0; x < 16; x++) { | |
233 | T[x] = key[x]; | |
236 | 234 | T[x + 16] = 0; |
237 | 235 | } |
238 | 236 | } else if (keylen == 24) { |
239 | for (x = 0; x < 24; x++) { | |
240 | T[x] = key[x]; | |
237 | for (x = 0; x < 24; x++) { | |
238 | T[x] = key[x]; | |
241 | 239 | } |
242 | for (x = 24; x < 32; x++) { | |
243 | T[x] = key[x-8] ^ 0xFF; | |
240 | for (x = 24; x < 32; x++) { | |
241 | T[x] = key[x-8] ^ 0xFF; | |
244 | 242 | } |
245 | 243 | } else { |
246 | for (x = 0; x < 32; x++) { | |
247 | T[x] = key[x]; | |
244 | for (x = 0; x < 32; x++) { | |
245 | T[x] = key[x]; | |
248 | 246 | } |
249 | 247 | } |
250 | 248 | |
251 | for (x = 0; x < 16; x++) { | |
249 | for (x = 0; x < 16; x++) { | |
252 | 250 | kL[x] = T[x]; |
253 | 251 | kR[x] = T[x + 16]; |
254 | 252 | } |
259 | 257 | |
260 | 258 | /* first two rounds */ |
261 | 259 | LOAD64H(A, T+32); LOAD64H(B, T+40); |
262 | B ^= F(A ^ key_sigma[0]); | |
263 | A ^= F(B ^ key_sigma[1]); | |
260 | B ^= F(A ^ key_sigma[0]); | |
261 | A ^= F(B ^ key_sigma[1]); | |
264 | 262 | STORE64H(A, T+32); STORE64H(B, T+40); |
265 | 263 | |
266 | 264 | /* xor kL in */ |
268 | 266 | |
269 | 267 | /* next two rounds */ |
270 | 268 | LOAD64H(A, T+32); LOAD64H(B, T+40); |
271 | B ^= F(A ^ key_sigma[2]); | |
272 | A ^= F(B ^ key_sigma[3]); | |
269 | B ^= F(A ^ key_sigma[2]); | |
270 | A ^= F(B ^ key_sigma[3]); | |
273 | 271 | STORE64H(A, T+32); STORE64H(B, T+40); |
274 | 272 | |
275 | 273 | /* grab KA */ |
285 | 283 | |
286 | 284 | /* k1-k2 */ |
287 | 285 | LOAD64H(skey->camellia.k[0], kA); |
288 | LOAD64H(skey->camellia.k[1], kA+8); | |
286 | LOAD64H(skey->camellia.k[1], kA+8); | |
289 | 287 | |
290 | 288 | /* rotate kL by 15, k3/k4 */ |
291 | 289 | rot_128(kL, 15, T+32); |
317 | 315 | rot_128(kA, 60, T+32); |
318 | 316 | LOAD64H(skey->camellia.k[10], T+32); |
319 | 317 | LOAD64H(skey->camellia.k[11], T+40); |
320 | ||
318 | ||
321 | 319 | /* rotate kL by 77, kl3, kl4 */ |
322 | 320 | rot_128(kL, 77, T+32); |
323 | 321 | LOAD64H(skey->camellia.kl[2], T+32); |
345 | 343 | } else { |
346 | 344 | /* last two rounds */ |
347 | 345 | LOAD64H(A, T+32); LOAD64H(B, T+40); |
348 | B ^= F(A ^ key_sigma[4]); | |
349 | A ^= F(B ^ key_sigma[5]); | |
346 | B ^= F(A ^ key_sigma[4]); | |
347 | A ^= F(B ^ key_sigma[5]); | |
350 | 348 | STORE64H(A, T+32); STORE64H(B, T+40); |
351 | 349 | |
352 | 350 | /* grab kB */ |
439 | 437 | return CRYPT_OK; |
440 | 438 | } |
441 | 439 | |
442 | int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
440 | int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
443 | 441 | { |
444 | 442 | ulong64 L, R; |
445 | 443 | ulong32 a, b; |
446 | 444 | |
447 | LOAD64H(L, pt+0); LOAD64H(R, pt+8); | |
445 | LOAD64H(L, pt+0); LOAD64H(R, pt+8); | |
448 | 446 | L ^= skey->camellia.kw[0]; |
449 | 447 | R ^= skey->camellia.kw[1]; |
450 | 448 | |
538 | 536 | ulong64 L, R; |
539 | 537 | ulong32 a, b; |
540 | 538 | |
541 | LOAD64H(R, ct+0); LOAD64H(L, ct+8); | |
539 | LOAD64H(R, ct+0); LOAD64H(L, ct+8); | |
542 | 540 | L ^= skey->camellia.kw[3]; |
543 | 541 | R ^= skey->camellia.kw[2]; |
544 | 542 | |
628 | 626 | return CRYPT_OK; |
629 | 627 | } |
630 | 628 | |
631 | int camellia_test(void) | |
632 | { | |
633 | static const struct { | |
634 | int keylen; | |
629 | int camellia_test(void) | |
630 | { | |
631 | static const struct { | |
632 | int keylen; | |
635 | 633 | unsigned char key[32], pt[16], ct[16]; |
636 | 634 | } tests[] = { |
637 | 635 | |
638 | 636 | { |
639 | 16, | |
640 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
637 | 16, | |
638 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
641 | 639 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, |
642 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
640 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
643 | 641 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, |
644 | { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, | |
642 | { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, | |
645 | 643 | 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 } |
646 | 644 | }, |
647 | 645 | |
648 | 646 | { |
649 | 24, | |
650 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
647 | 24, | |
648 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
651 | 649 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, |
652 | 650 | 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, |
653 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
651 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
654 | 652 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, |
655 | { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, | |
653 | { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, | |
656 | 654 | 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 } |
657 | 655 | }, |
658 | 656 | |
659 | 657 | |
660 | 658 | { |
661 | 32, | |
662 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
659 | 32, | |
660 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
663 | 661 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, |
664 | 662 | 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, |
665 | 663 | 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, |
666 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
664 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, | |
667 | 665 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, |
668 | { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, | |
666 | { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, | |
669 | 667 | 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 } |
668 | }, | |
669 | ||
670 | { | |
671 | 32, | |
672 | { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, | |
673 | 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, | |
674 | 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, | |
675 | 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }, | |
676 | { 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, | |
677 | 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 }, | |
678 | { 0x79, 0x60, 0x10, 0x9F, 0xB6, 0xDC, 0x42, 0x94, | |
679 | 0x7F, 0xCF, 0xE5, 0x9E, 0xA3, 0xC5, 0xEB, 0x6B } | |
670 | 680 | } |
671 | 681 | }; |
672 | 682 | unsigned char buf[2][16]; |
673 | 683 | symmetric_key skey; |
674 | int err, x; | |
675 | ||
676 | for (x = 0; x < 3; x++) { | |
677 | if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { | |
684 | int err; | |
685 | unsigned int x; | |
686 | ||
687 | for (x = 0; x < sizeof(tests)/sizeof(tests[0]); x++) { | |
688 | zeromem(&skey, sizeof(skey)); | |
689 | if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { | |
678 | 690 | return err; |
679 | 691 | } |
680 | 692 | if ((err = camellia_ecb_encrypt(tests[x].pt, buf[0], &skey)) != CRYPT_OK) { |
1561 | 1561 | return CRYPT_INVALID_ROUNDS; |
1562 | 1562 | } |
1563 | 1563 | |
1564 | if (keylen != 24) { | |
1564 | if (keylen != 24 && keylen != 16) { | |
1565 | 1565 | return CRYPT_INVALID_KEYSIZE; |
1566 | 1566 | } |
1567 | 1567 | |
1568 | 1568 | deskey(key, EN0, skey->des3.ek[0]); |
1569 | 1569 | deskey(key+8, DE1, skey->des3.ek[1]); |
1570 | deskey(key+16, EN0, skey->des3.ek[2]); | |
1570 | if (keylen == 24) { | |
1571 | deskey(key+16, EN0, skey->des3.ek[2]); | |
1572 | } else { | |
1573 | /* two-key 3DES: K3=K1 */ | |
1574 | deskey(key, EN0, skey->des3.ek[2]); | |
1575 | } | |
1571 | 1576 | |
1572 | 1577 | deskey(key, DE1, skey->des3.dk[2]); |
1573 | 1578 | deskey(key+8, EN0, skey->des3.dk[1]); |
1574 | deskey(key+16, DE1, skey->des3.dk[0]); | |
1579 | if (keylen == 24) { | |
1580 | deskey(key+16, DE1, skey->des3.dk[0]); | |
1581 | } else { | |
1582 | /* two-key 3DES: K3=K1 */ | |
1583 | deskey(key, DE1, skey->des3.dk[0]); | |
1584 | } | |
1575 | 1585 | |
1576 | 1586 | return CRYPT_OK; |
1577 | 1587 | } |
31 | 31 | |
32 | 32 | #ifdef LTC_SAFER |
33 | 33 | |
34 | const struct ltc_cipher_descriptor | |
34 | #define __LTC_SAFER_TAB_C__ | |
35 | #include "safer_tab.c.inc" | |
36 | ||
37 | const struct ltc_cipher_descriptor | |
35 | 38 | safer_k64_desc = { |
36 | "safer-k64", | |
39 | "safer-k64", | |
37 | 40 | 8, 8, 8, 8, LTC_SAFER_K64_DEFAULT_NOF_ROUNDS, |
38 | 41 | &safer_k64_setup, |
39 | 42 | &safer_ecb_encrypt, |
94 | 97 | #define IPHT(x, y) { x -= y; y -= x; } |
95 | 98 | |
96 | 99 | /******************* Types ****************************************************/ |
97 | extern const unsigned char safer_ebox[], safer_lbox[]; | |
98 | 100 | |
99 | 101 | #ifdef LTC_CLEAN_STACK |
100 | 102 | static void _Safer_Expand_Userkey(const unsigned char *userkey_1, |
157 | 159 | } |
158 | 160 | } |
159 | 161 | } |
160 | ||
162 | ||
161 | 163 | #ifdef LTC_CLEAN_STACK |
162 | 164 | zeromem(ka, sizeof(ka)); |
163 | 165 | zeromem(kb, sizeof(kb)); |
192 | 194 | Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); |
193 | 195 | return CRYPT_OK; |
194 | 196 | } |
195 | ||
197 | ||
196 | 198 | int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) |
197 | 199 | { |
198 | 200 | LTC_ARGCHK(key != NULL); |
379 | 381 | { |
380 | 382 | #ifndef LTC_TEST |
381 | 383 | return CRYPT_NOP; |
382 | #else | |
384 | #else | |
383 | 385 | static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, |
384 | 386 | k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, |
385 | 387 | k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; |
408 | 410 | { |
409 | 411 | #ifndef LTC_TEST |
410 | 412 | return CRYPT_NOP; |
411 | #else | |
413 | #else | |
412 | 414 | static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, |
413 | 415 | sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, |
414 | 416 | sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; |
439 | 441 | #endif |
440 | 442 | } |
441 | 443 | |
442 | /** Terminate the context | |
444 | /** Terminate the context | |
443 | 445 | @param skey The scheduled key |
444 | 446 | */ |
445 | 447 | void safer_done(symmetric_key *skey) |
450 | 452 | { |
451 | 453 | #ifndef LTC_TEST |
452 | 454 | return CRYPT_NOP; |
453 | #else | |
455 | #else | |
454 | 456 | static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, |
455 | 457 | sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, |
456 | 458 | 0, 0, 0, 0, 0, 0, 0, 0 }, |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | ||
11 | /** | |
12 | @file safer_tab.c | |
13 | Tables for LTC_SAFER block ciphers | |
14 | */ | |
15 | ||
16 | #include "tomcrypt.h" | |
17 | ||
18 | #if defined(LTC_SAFERP) || defined(LTC_SAFER) | |
19 | ||
20 | /* This is the box defined by ebox[x] = 45^x mod 257. | |
21 | * Its assumed that the value "256" corresponds to zero. */ | |
22 | const unsigned char safer_ebox[256] = { | |
23 | 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, | |
24 | 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, | |
25 | 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, | |
26 | 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, | |
27 | 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, | |
28 | 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, | |
29 | 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, | |
30 | 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, | |
31 | 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, | |
32 | 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, | |
33 | 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, | |
34 | 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, | |
35 | 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, | |
36 | 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, | |
37 | 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, | |
38 | 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 | |
39 | }; | |
40 | ||
41 | /* This is the inverse of ebox or the base 45 logarithm */ | |
42 | const unsigned char safer_lbox[256] = { | |
43 | 128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, | |
44 | 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, | |
45 | 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, | |
46 | 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, | |
47 | 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, | |
48 | 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, | |
49 | 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, | |
50 | 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, | |
51 | 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, | |
52 | 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, | |
53 | 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, | |
54 | 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, | |
55 | 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, | |
56 | 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, | |
57 | 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, | |
58 | 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 | |
59 | }; | |
60 | ||
61 | #endif | |
62 | ||
63 | ||
64 | ||
65 | /* $Source$ */ | |
66 | /* $Revision$ */ | |
67 | /* $Date$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | ||
11 | /** | |
12 | @file safer_tab.c | |
13 | Tables for LTC_SAFER block ciphers | |
14 | */ | |
15 | ||
16 | #ifdef __LTC_SAFER_TAB_C__ | |
17 | ||
18 | /* This is the box defined by ebox[x] = 45^x mod 257. | |
19 | * Its assumed that the value "256" corresponds to zero. */ | |
20 | static const unsigned char safer_ebox[256] = { | |
21 | 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, | |
22 | 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, | |
23 | 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, | |
24 | 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, | |
25 | 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, | |
26 | 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, | |
27 | 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, | |
28 | 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, | |
29 | 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, | |
30 | 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, | |
31 | 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, | |
32 | 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, | |
33 | 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, | |
34 | 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, | |
35 | 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, | |
36 | 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 | |
37 | }; | |
38 | ||
39 | /* This is the inverse of ebox or the base 45 logarithm */ | |
40 | static const unsigned char safer_lbox[256] = { | |
41 | 128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, | |
42 | 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, | |
43 | 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, | |
44 | 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, | |
45 | 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, | |
46 | 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, | |
47 | 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, | |
48 | 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, | |
49 | 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, | |
50 | 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, | |
51 | 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, | |
52 | 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, | |
53 | 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, | |
54 | 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, | |
55 | 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, | |
56 | 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 | |
57 | }; | |
58 | ||
59 | #endif /* __LTC_SAFER_TAB_C__ */ | |
60 | ||
61 | ||
62 | ||
63 | /* $Source$ */ | |
64 | /* $Revision$ */ | |
65 | /* $Date$ */ |
8 | 8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
9 | 9 | */ |
10 | 10 | |
11 | /** | |
11 | /** | |
12 | 12 | @file saferp.c |
13 | LTC_SAFER+ Implementation by Tom St Denis | |
13 | LTC_SAFER+ Implementation by Tom St Denis | |
14 | 14 | */ |
15 | 15 | #include "tomcrypt.h" |
16 | 16 | |
17 | 17 | #ifdef LTC_SAFERP |
18 | ||
19 | #define __LTC_SAFER_TAB_C__ | |
20 | #include "safer_tab.c.inc" | |
18 | 21 | |
19 | 22 | const struct ltc_cipher_descriptor saferp_desc = |
20 | 23 | { |
30 | 33 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL |
31 | 34 | }; |
32 | 35 | |
33 | /* ROUND(b,i) | |
36 | /* ROUND(b,i) | |
34 | 37 | * |
35 | * This is one forward key application. Note the basic form is | |
36 | * key addition, substitution, key addition. The safer_ebox and safer_lbox | |
37 | * are the exponentiation box and logarithm boxes respectively. | |
38 | * The value of 'i' is the current round number which allows this | |
39 | * function to be unrolled massively. Most of LTC_SAFER+'s speed | |
40 | * comes from not having to compute indirect accesses into the | |
38 | * This is one forward key application. Note the basic form is | |
39 | * key addition, substitution, key addition. The safer_ebox and safer_lbox | |
40 | * are the exponentiation box and logarithm boxes respectively. | |
41 | * The value of 'i' is the current round number which allows this | |
42 | * function to be unrolled massively. Most of LTC_SAFER+'s speed | |
43 | * comes from not having to compute indirect accesses into the | |
41 | 44 | * array of 16 bytes b[0..15] which is the block of data |
42 | 45 | */ |
43 | ||
44 | extern const unsigned char safer_ebox[], safer_lbox[]; | |
45 | 46 | |
46 | 47 | #define ROUND(b, i) \ |
47 | 48 | b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ |
59 | 60 | b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ |
60 | 61 | b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ |
61 | 62 | b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ |
62 | b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; | |
63 | b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; | |
63 | 64 | |
64 | 65 | /* This is one inverse key application */ |
65 | 66 | #define iROUND(b, i) \ |
89 | 90 | b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \ |
90 | 91 | b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \ |
91 | 92 | b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \ |
92 | b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; | |
93 | b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; | |
93 | 94 | |
94 | 95 | /* This is an inverse single layer PHT transform */ |
95 | 96 | #define iPHT(b) \ |
116 | 117 | b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ |
117 | 118 | b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; |
118 | 119 | |
119 | /* The complete forward Linear Transform layer. | |
120 | * Note that alternating usage of b and b2. | |
121 | * Each round of LT starts in 'b' and ends in 'b2'. | |
120 | /* The complete forward Linear Transform layer. | |
121 | * Note that alternating usage of b and b2. | |
122 | * Each round of LT starts in 'b' and ends in 'b2'. | |
122 | 123 | */ |
123 | 124 | #define LT(b, b2) \ |
124 | 125 | PHT(b); SHUF(b, b2); \ |
125 | 126 | PHT(b2); SHUF(b2, b); \ |
126 | 127 | PHT(b); SHUF(b, b2); \ |
127 | PHT(b2); | |
128 | PHT(b2); | |
128 | 129 | |
129 | 130 | /* This is the inverse linear transform layer. */ |
130 | 131 | #define iLT(b, b2) \ |
132 | 133 | iSHUF(b, b2); iPHT(b2); \ |
133 | 134 | iSHUF(b2, b); iPHT(b); \ |
134 | 135 | iSHUF(b, b2); iPHT(b2); |
135 | ||
136 | #ifdef LTC_SMALL_CODE | |
137 | ||
138 | static void _round(unsigned char *b, int i, symmetric_key *skey) | |
136 | ||
137 | #ifdef LTC_SMALL_CODE | |
138 | ||
139 | static void _round(unsigned char *b, int i, symmetric_key *skey) | |
139 | 140 | { |
140 | 141 | ROUND(b, i); |
141 | 142 | } |
153 | 154 | static void _ilt(unsigned char *b, unsigned char *b2) |
154 | 155 | { |
155 | 156 | iLT(b, b2); |
156 | } | |
157 | } | |
157 | 158 | |
158 | 159 | #undef ROUND |
159 | 160 | #define ROUND(b, i) _round(b, i, skey) |
227 | 228 | } |
228 | 229 | |
229 | 230 | /* Is the number of rounds valid? Either use zero for default or |
230 | * 8,12,16 rounds for 16,24,32 byte keys | |
231 | * 8,12,16 rounds for 16,24,32 byte keys | |
231 | 232 | */ |
232 | 233 | if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) { |
233 | 234 | return CRYPT_INVALID_ROUNDS; |
236 | 237 | /* 128 bit key version */ |
237 | 238 | if (keylen == 16) { |
238 | 239 | /* copy key into t */ |
239 | for (x = y = 0; x < 16; x++) { | |
240 | t[x] = key[x]; | |
241 | y ^= key[x]; | |
240 | for (x = y = 0; x < 16; x++) { | |
241 | t[x] = key[x]; | |
242 | y ^= key[x]; | |
242 | 243 | } |
243 | 244 | t[16] = y; |
244 | 245 | |
264 | 265 | skey->saferp.rounds = 8; |
265 | 266 | } else if (keylen == 24) { |
266 | 267 | /* copy key into t */ |
267 | for (x = y = 0; x < 24; x++) { | |
268 | t[x] = key[x]; | |
269 | y ^= key[x]; | |
268 | for (x = y = 0; x < 24; x++) { | |
269 | t[x] = key[x]; | |
270 | y ^= key[x]; | |
270 | 271 | } |
271 | 272 | t[24] = y; |
272 | 273 | |
283 | 284 | |
284 | 285 | /* select and add */ |
285 | 286 | z = x; |
286 | for (y = 0; y < 16; y++) { | |
287 | for (y = 0; y < 16; y++) { | |
287 | 288 | skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; |
288 | 289 | if (++z == 25) { z = 0; } |
289 | 290 | } |
291 | 292 | skey->saferp.rounds = 12; |
292 | 293 | } else { |
293 | 294 | /* copy key into t */ |
294 | for (x = y = 0; x < 32; x++) { | |
295 | t[x] = key[x]; | |
296 | y ^= key[x]; | |
295 | for (x = y = 0; x < 32; x++) { | |
296 | t[x] = key[x]; | |
297 | y ^= key[x]; | |
297 | 298 | } |
298 | 299 | t[32] = y; |
299 | 300 | |
300 | 301 | /* make round keys */ |
301 | for (x = 0; x < 16; x++) { | |
302 | for (x = 0; x < 16; x++) { | |
302 | 303 | skey->saferp.K[0][x] = t[x]; |
303 | 304 | } |
304 | 305 | |
307 | 308 | for (y = 0; y < 33; y++) { |
308 | 309 | t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; |
309 | 310 | } |
310 | ||
311 | ||
311 | 312 | /* select and add */ |
312 | 313 | z = x; |
313 | 314 | for (y = 0; y < 16; y++) { |
391 | 392 | Decrypts a block of text with LTC_SAFER+ |
392 | 393 | @param ct The input ciphertext (16 bytes) |
393 | 394 | @param pt The output plaintext (16 bytes) |
394 | @param skey The key as scheduled | |
395 | @param skey The key as scheduled | |
395 | 396 | @return CRYPT_OK if successful |
396 | 397 | */ |
397 | 398 | int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) |
459 | 460 | { |
460 | 461 | #ifndef LTC_TEST |
461 | 462 | return CRYPT_NOP; |
462 | #else | |
463 | #else | |
463 | 464 | static const struct { |
464 | 465 | int keylen; |
465 | 466 | unsigned char key[32], pt[16], ct[16]; |
466 | 467 | } tests[] = { |
467 | 468 | { |
468 | 469 | 16, |
469 | { 41, 35, 190, 132, 225, 108, 214, 174, | |
470 | { 41, 35, 190, 132, 225, 108, 214, 174, | |
470 | 471 | 82, 144, 73, 241, 241, 187, 233, 235 }, |
471 | { 179, 166, 219, 60, 135, 12, 62, 153, | |
472 | { 179, 166, 219, 60, 135, 12, 62, 153, | |
472 | 473 | 36, 94, 13, 28, 6, 183, 71, 222 }, |
473 | { 224, 31, 182, 10, 12, 255, 84, 70, | |
474 | { 224, 31, 182, 10, 12, 255, 84, 70, | |
474 | 475 | 127, 13, 89, 249, 9, 57, 165, 220 } |
475 | 476 | }, { |
476 | 477 | 24, |
477 | { 72, 211, 143, 117, 230, 217, 29, 42, | |
478 | 229, 192, 247, 43, 120, 129, 135, 68, | |
478 | { 72, 211, 143, 117, 230, 217, 29, 42, | |
479 | 229, 192, 247, 43, 120, 129, 135, 68, | |
479 | 480 | 14, 95, 80, 0, 212, 97, 141, 190 }, |
480 | { 123, 5, 21, 7, 59, 51, 130, 31, | |
481 | { 123, 5, 21, 7, 59, 51, 130, 31, | |
481 | 482 | 24, 112, 146, 218, 100, 84, 206, 177 }, |
482 | { 92, 136, 4, 63, 57, 95, 100, 0, | |
483 | { 92, 136, 4, 63, 57, 95, 100, 0, | |
483 | 484 | 150, 130, 130, 16, 193, 111, 219, 133 } |
484 | 485 | }, { |
485 | 486 | 32, |
486 | { 243, 168, 141, 254, 190, 242, 235, 113, | |
487 | { 243, 168, 141, 254, 190, 242, 235, 113, | |
487 | 488 | 255, 160, 208, 59, 117, 6, 140, 126, |
488 | 135, 120, 115, 77, 208, 190, 130, 190, | |
489 | 135, 120, 115, 77, 208, 190, 130, 190, | |
489 | 490 | 219, 194, 70, 65, 43, 140, 250, 48 }, |
490 | { 127, 112, 240, 167, 84, 134, 50, 149, | |
491 | { 127, 112, 240, 167, 84, 134, 50, 149, | |
491 | 492 | 170, 91, 104, 19, 11, 230, 252, 245 }, |
492 | { 88, 11, 25, 36, 172, 229, 202, 213, | |
493 | { 88, 11, 25, 36, 172, 229, 202, 213, | |
493 | 494 | 170, 65, 105, 153, 220, 104, 153, 138 } |
494 | 495 | } |
495 | }; | |
496 | }; | |
496 | 497 | |
497 | 498 | unsigned char tmp[2][16]; |
498 | 499 | symmetric_key skey; |
506 | 507 | saferp_ecb_decrypt(tmp[0], tmp[1], &skey); |
507 | 508 | |
508 | 509 | /* compare */ |
509 | if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { | |
510 | if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { | |
510 | 511 | return CRYPT_FAIL_TESTVECTOR; |
511 | 512 | } |
512 | 513 | |
521 | 522 | #endif |
522 | 523 | } |
523 | 524 | |
524 | /** Terminate the context | |
525 | /** Terminate the context | |
525 | 526 | @param skey The scheduled key |
526 | 527 | */ |
527 | 528 | void saferp_done(symmetric_key *skey) |
536 | 537 | int saferp_keysize(int *keysize) |
537 | 538 | { |
538 | 539 | LTC_ARGCHK(keysize != NULL); |
539 | ||
540 | ||
540 | 541 | if (*keysize < 16) |
541 | 542 | return CRYPT_INVALID_KEYSIZE; |
542 | 543 | if (*keysize < 24) { |
61 | 61 | |
62 | 62 | #ifdef LTC_TWOFISH_TABLES |
63 | 63 | |
64 | #define __LTC_TWOFISH_TAB_C__ | |
64 | 65 | #include "twofish_tab.c.inc" |
65 | 66 | |
66 | 67 | #define sbox(i, x) ((ulong32)SBOX[i][(x)&255]) |
18 | 18 | |
19 | 19 | /** |
20 | 20 | CCM encrypt/decrypt and produce an authentication tag |
21 | ||
22 | *1 'pt' and 'ct' can both be 'in' or 'out', depending on 'direction' | |
23 | ||
21 | 24 | @param cipher The index of the cipher desired |
22 | 25 | @param key The secret key to use |
23 | 26 | @param keylen The length of the secret key (octets) |
26 | 29 | @param noncelen The length of the nonce |
27 | 30 | @param header The header for the session |
28 | 31 | @param headerlen The length of the header (octets) |
29 | @param pt [out] The plaintext | |
32 | @param pt [*1] The plaintext | |
30 | 33 | @param ptlen The length of the plaintext (octets) |
31 | @param ct [out] The ciphertext | |
34 | @param ct [*1] The ciphertext | |
32 | 35 | @param tag [out] The destination tag |
33 | 36 | @param taglen [in/out] The max size and resulting size of the authentication tag |
34 | 37 | @param direction Encrypt or Decrypt direction (0 or 1) |
94 | 97 | nonce, noncelen, |
95 | 98 | header, headerlen, |
96 | 99 | pt, ptlen, |
97 | ct, | |
100 | ct, | |
98 | 101 | tag, taglen, |
99 | 102 | direction); |
100 | 103 | } |
173 | 176 | /* handle header */ |
174 | 177 | if (headerlen > 0) { |
175 | 178 | x = 0; |
176 | ||
179 | ||
177 | 180 | /* store length */ |
178 | 181 | if (headerlen < ((1UL<<16) - (1UL<<8))) { |
179 | 182 | PAD[x++] ^= (headerlen>>8) & 255; |
212 | 215 | |
213 | 216 | /* flags */ |
214 | 217 | ctr[x++] = (unsigned char)L-1; |
215 | ||
218 | ||
216 | 219 | /* nonce */ |
217 | 220 | for (y = 0; y < (16 - (L+1)); ++y) { |
218 | 221 | ctr[x++] = nonce[y]; |
304 | 307 | } |
305 | 308 | PAD[x++] ^= b; |
306 | 309 | } |
307 | ||
310 | ||
308 | 311 | if (x != 0) { |
309 | 312 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { |
310 | 313 | goto error; |
14 | 14 | CCM support, process a block of memory, Tom St Denis |
15 | 15 | */ |
16 | 16 | |
17 | #ifdef CCM_MODE | |
17 | #if defined LTC_CCM_MODE && 0 | |
18 | 18 | |
19 | 19 | /** |
20 | 20 | CCM encrypt/decrypt and produce an authentication tag |
65 | 65 | } |
66 | 66 | gcm_mult_h(gcm, gcm->X); |
67 | 67 | |
68 | /* copy counter out */ | |
68 | /* copy counter out */ | |
69 | 69 | XMEMCPY(gcm->Y, gcm->X, 16); |
70 | 70 | zeromem(gcm->X, 16); |
71 | 71 | } else { |
116 | 116 | return CRYPT_OK; |
117 | 117 | } |
118 | 118 | #endif |
119 | ||
119 | ||
120 | 120 | |
121 | 121 | /* $Source$ */ |
122 | 122 | /* $Revision$ */ |
23 | 23 | @param IVlen The length of the IV |
24 | 24 | @return CRYPT_OK on success |
25 | 25 | */ |
26 | int gcm_add_iv(gcm_state *gcm, | |
26 | int gcm_add_iv(gcm_state *gcm, | |
27 | 27 | const unsigned char *IV, unsigned long IVlen) |
28 | 28 | { |
29 | 29 | unsigned long x, y; |
38 | 38 | if (gcm->mode != LTC_GCM_MODE_IV) { |
39 | 39 | return CRYPT_INVALID_ARG; |
40 | 40 | } |
41 | ||
41 | ||
42 | 42 | if (gcm->buflen >= 16 || gcm->buflen < 0) { |
43 | 43 | return CRYPT_INVALID_ARG; |
44 | 44 | } |
86 | 86 | } |
87 | 87 | |
88 | 88 | #endif |
89 | ||
89 | ||
90 | 90 | |
91 | 91 | /* $Source$ */ |
92 | 92 | /* $Revision$ */ |
45 | 45 | #endif /* LTC_FAST */ |
46 | 46 | } |
47 | 47 | #endif /* LTC_GCM_TABLES_SSE2 */ |
48 | #else | |
49 | gcm_gf_mult(gcm->H, I, T); | |
48 | #else | |
49 | gcm_gf_mult(gcm->H, I, T); | |
50 | 50 | #endif |
51 | 51 | XMEMCPY(I, T, 16); |
52 | 52 | } |
16 | 16 | |
17 | 17 | #ifdef LTC_GCM_MODE |
18 | 18 | |
19 | /** | |
19 | /** | |
20 | 20 | Process plaintext/ciphertext through GCM |
21 | @param gcm The GCM state | |
21 | @param gcm The GCM state | |
22 | 22 | @param pt The plaintext |
23 | 23 | @param ptlen The plaintext length (ciphertext length is the same) |
24 | 24 | @param ct The ciphertext |
43 | 43 | if (gcm->buflen > 16 || gcm->buflen < 0) { |
44 | 44 | return CRYPT_INVALID_ARG; |
45 | 45 | } |
46 | ||
46 | ||
47 | 47 | if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { |
48 | 48 | return err; |
49 | 49 | } |
76 | 76 | x = 0; |
77 | 77 | #ifdef LTC_FAST |
78 | 78 | if (gcm->buflen == 0) { |
79 | if (direction == GCM_ENCRYPT) { | |
79 | if (direction == GCM_ENCRYPT) { | |
80 | 80 | for (x = 0; x < (ptlen & ~15); x += 16) { |
81 | 81 | /* ctr encrypt */ |
82 | 82 | for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { |
114 | 114 | } |
115 | 115 | } |
116 | 116 | } |
117 | #endif | |
117 | #endif | |
118 | 118 | |
119 | 119 | /* process text */ |
120 | 120 | for (; x < ptlen; x++) { |
121 | 121 | if (gcm->buflen == 16) { |
122 | 122 | gcm->pttotlen += 128; |
123 | 123 | gcm_mult_h(gcm, gcm->X); |
124 | ||
124 | ||
125 | 125 | /* increment counter */ |
126 | 126 | for (y = 15; y >= 12; y--) { |
127 | 127 | if (++gcm->Y[y] & 255) { break; } |
133 | 133 | } |
134 | 134 | |
135 | 135 | if (direction == GCM_ENCRYPT) { |
136 | b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen]; | |
136 | b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen]; | |
137 | 137 | } else { |
138 | 138 | b = ct[x]; |
139 | 139 | pt[x] = ct[x] ^ gcm->buf[gcm->buflen]; |
140 | 140 | } |
141 | gcm->X[gcm->buflen++] ^= b; | |
141 | gcm->X[gcm->buflen++] ^= b; | |
142 | 142 | } |
143 | 143 | |
144 | 144 | return CRYPT_OK; |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | /** | |
11 | @param sha224.c | |
12 | LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis) | |
13 | */ | |
14 | ||
15 | #include "tomcrypt.h" | |
16 | ||
17 | #if defined(LTC_SHA224) && defined(LTC_SHA256) | |
18 | ||
19 | const struct ltc_hash_descriptor sha224_desc = | |
20 | { | |
21 | "sha224", | |
22 | 10, | |
23 | 28, | |
24 | 64, | |
25 | ||
26 | /* OID */ | |
27 | { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, | |
28 | 9, | |
29 | ||
30 | &sha224_init, | |
31 | &sha256_process, | |
32 | &sha224_done, | |
33 | &sha224_test, | |
34 | NULL | |
35 | }; | |
36 | ||
37 | /* init the sha256 er... sha224 state ;-) */ | |
38 | /** | |
39 | Initialize the hash state | |
40 | @param md The hash state you wish to initialize | |
41 | @return CRYPT_OK if successful | |
42 | */ | |
43 | int sha224_init(hash_state * md) | |
44 | { | |
45 | LTC_ARGCHK(md != NULL); | |
46 | ||
47 | md->sha256.curlen = 0; | |
48 | md->sha256.length = 0; | |
49 | md->sha256.state[0] = 0xc1059ed8UL; | |
50 | md->sha256.state[1] = 0x367cd507UL; | |
51 | md->sha256.state[2] = 0x3070dd17UL; | |
52 | md->sha256.state[3] = 0xf70e5939UL; | |
53 | md->sha256.state[4] = 0xffc00b31UL; | |
54 | md->sha256.state[5] = 0x68581511UL; | |
55 | md->sha256.state[6] = 0x64f98fa7UL; | |
56 | md->sha256.state[7] = 0xbefa4fa4UL; | |
57 | return CRYPT_OK; | |
58 | } | |
59 | ||
60 | /** | |
61 | Terminate the hash to get the digest | |
62 | @param md The hash state | |
63 | @param out [out] The destination of the hash (28 bytes) | |
64 | @return CRYPT_OK if successful | |
65 | */ | |
66 | int sha224_done(hash_state * md, unsigned char *out) | |
67 | { | |
68 | unsigned char buf[32]; | |
69 | int err; | |
70 | ||
71 | LTC_ARGCHK(md != NULL); | |
72 | LTC_ARGCHK(out != NULL); | |
73 | ||
74 | err = sha256_done(md, buf); | |
75 | XMEMCPY(out, buf, 28); | |
76 | #ifdef LTC_CLEAN_STACK | |
77 | zeromem(buf, sizeof(buf)); | |
78 | #endif | |
79 | return err; | |
80 | } | |
81 | ||
82 | /** | |
83 | Self-test the hash | |
84 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled | |
85 | */ | |
86 | int sha224_test(void) | |
87 | { | |
88 | #ifndef LTC_TEST | |
89 | return CRYPT_NOP; | |
90 | #else | |
91 | static const struct { | |
92 | char *msg; | |
93 | unsigned char hash[28]; | |
94 | } tests[] = { | |
95 | { "abc", | |
96 | { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, | |
97 | 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, | |
98 | 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, | |
99 | 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } | |
100 | }, | |
101 | { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", | |
102 | { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, | |
103 | 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, | |
104 | 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, | |
105 | 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } | |
106 | }, | |
107 | }; | |
108 | ||
109 | int i; | |
110 | unsigned char tmp[28]; | |
111 | hash_state md; | |
112 | ||
113 | for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { | |
114 | sha224_init(&md); | |
115 | sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); | |
116 | sha224_done(&md, tmp); | |
117 | if (XMEMCMP(tmp, tests[i].hash, 28) != 0) { | |
118 | return CRYPT_FAIL_TESTVECTOR; | |
119 | } | |
120 | } | |
121 | return CRYPT_OK; | |
122 | #endif | |
123 | } | |
124 | ||
125 | #endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */ | |
126 | ||
127 | ||
128 | /* $Source$ */ | |
129 | /* $Revision$ */ | |
130 | /* $Date$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | /** | |
11 | @param sha224.c | |
12 | LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis) | |
13 | */ | |
14 | ||
15 | const struct ltc_hash_descriptor sha224_desc = | |
16 | { | |
17 | "sha224", | |
18 | 10, | |
19 | 28, | |
20 | 64, | |
21 | ||
22 | /* OID */ | |
23 | { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, | |
24 | 9, | |
25 | ||
26 | &sha224_init, | |
27 | &sha256_process, | |
28 | &sha224_done, | |
29 | &sha224_test, | |
30 | NULL | |
31 | }; | |
32 | ||
33 | /* init the sha256 er... sha224 state ;-) */ | |
34 | /** | |
35 | Initialize the hash state | |
36 | @param md The hash state you wish to initialize | |
37 | @return CRYPT_OK if successful | |
38 | */ | |
39 | int sha224_init(hash_state * md) | |
40 | { | |
41 | LTC_ARGCHK(md != NULL); | |
42 | ||
43 | md->sha256.curlen = 0; | |
44 | md->sha256.length = 0; | |
45 | md->sha256.state[0] = 0xc1059ed8UL; | |
46 | md->sha256.state[1] = 0x367cd507UL; | |
47 | md->sha256.state[2] = 0x3070dd17UL; | |
48 | md->sha256.state[3] = 0xf70e5939UL; | |
49 | md->sha256.state[4] = 0xffc00b31UL; | |
50 | md->sha256.state[5] = 0x68581511UL; | |
51 | md->sha256.state[6] = 0x64f98fa7UL; | |
52 | md->sha256.state[7] = 0xbefa4fa4UL; | |
53 | return CRYPT_OK; | |
54 | } | |
55 | ||
56 | /** | |
57 | Terminate the hash to get the digest | |
58 | @param md The hash state | |
59 | @param out [out] The destination of the hash (28 bytes) | |
60 | @return CRYPT_OK if successful | |
61 | */ | |
62 | int sha224_done(hash_state * md, unsigned char *out) | |
63 | { | |
64 | unsigned char buf[32]; | |
65 | int err; | |
66 | ||
67 | LTC_ARGCHK(md != NULL); | |
68 | LTC_ARGCHK(out != NULL); | |
69 | ||
70 | err = sha256_done(md, buf); | |
71 | XMEMCPY(out, buf, 28); | |
72 | #ifdef LTC_CLEAN_STACK | |
73 | zeromem(buf, sizeof(buf)); | |
74 | #endif | |
75 | return err; | |
76 | } | |
77 | ||
78 | /** | |
79 | Self-test the hash | |
80 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled | |
81 | */ | |
82 | int sha224_test(void) | |
83 | { | |
84 | #ifndef LTC_TEST | |
85 | return CRYPT_NOP; | |
86 | #else | |
87 | static const struct { | |
88 | char *msg; | |
89 | unsigned char hash[28]; | |
90 | } tests[] = { | |
91 | { "abc", | |
92 | { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, | |
93 | 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, | |
94 | 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, | |
95 | 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } | |
96 | }, | |
97 | { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", | |
98 | { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, | |
99 | 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, | |
100 | 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, | |
101 | 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } | |
102 | }, | |
103 | }; | |
104 | ||
105 | int i; | |
106 | unsigned char tmp[28]; | |
107 | hash_state md; | |
108 | ||
109 | for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { | |
110 | sha224_init(&md); | |
111 | sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); | |
112 | sha224_done(&md, tmp); | |
113 | if (XMEMCMP(tmp, tests[i].hash, 28) != 0) { | |
114 | return CRYPT_FAIL_TESTVECTOR; | |
115 | } | |
116 | } | |
117 | return CRYPT_OK; | |
118 | #endif | |
119 | } | |
120 | ||
121 | ||
122 | /* $Source$ */ | |
123 | /* $Revision$ */ | |
124 | /* $Date$ */ |
326 | 326 | #endif |
327 | 327 | } |
328 | 328 | |
329 | #ifdef LTC_SHA224 | |
330 | #include "sha224.c.inc" | |
331 | #endif | |
332 | ||
333 | 329 | #endif |
334 | 330 | |
335 | 331 |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | /** | |
11 | @param sha384.c | |
12 | LTC_SHA384 hash included in sha512.c, Tom St Denis | |
13 | */ | |
14 | ||
15 | #include "tomcrypt.h" | |
16 | ||
17 | #if defined(LTC_SHA384) && defined(LTC_SHA512) | |
18 | ||
19 | const struct ltc_hash_descriptor sha384_desc = | |
20 | { | |
21 | "sha384", | |
22 | 4, | |
23 | 48, | |
24 | 128, | |
25 | ||
26 | /* OID */ | |
27 | { 2, 16, 840, 1, 101, 3, 4, 2, 2, }, | |
28 | 9, | |
29 | ||
30 | &sha384_init, | |
31 | &sha512_process, | |
32 | &sha384_done, | |
33 | &sha384_test, | |
34 | NULL | |
35 | }; | |
36 | ||
37 | /** | |
38 | Initialize the hash state | |
39 | @param md The hash state you wish to initialize | |
40 | @return CRYPT_OK if successful | |
41 | */ | |
42 | int sha384_init(hash_state * md) | |
43 | { | |
44 | LTC_ARGCHK(md != NULL); | |
45 | ||
46 | md->sha512.curlen = 0; | |
47 | md->sha512.length = 0; | |
48 | md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8); | |
49 | md->sha512.state[1] = CONST64(0x629a292a367cd507); | |
50 | md->sha512.state[2] = CONST64(0x9159015a3070dd17); | |
51 | md->sha512.state[3] = CONST64(0x152fecd8f70e5939); | |
52 | md->sha512.state[4] = CONST64(0x67332667ffc00b31); | |
53 | md->sha512.state[5] = CONST64(0x8eb44a8768581511); | |
54 | md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); | |
55 | md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); | |
56 | return CRYPT_OK; | |
57 | } | |
58 | ||
59 | /** | |
60 | Terminate the hash to get the digest | |
61 | @param md The hash state | |
62 | @param out [out] The destination of the hash (48 bytes) | |
63 | @return CRYPT_OK if successful | |
64 | */ | |
65 | int sha384_done(hash_state * md, unsigned char *out) | |
66 | { | |
67 | unsigned char buf[64]; | |
68 | ||
69 | LTC_ARGCHK(md != NULL); | |
70 | LTC_ARGCHK(out != NULL); | |
71 | ||
72 | if (md->sha512.curlen >= sizeof(md->sha512.buf)) { | |
73 | return CRYPT_INVALID_ARG; | |
74 | } | |
75 | ||
76 | sha512_done(md, buf); | |
77 | XMEMCPY(out, buf, 48); | |
78 | #ifdef LTC_CLEAN_STACK | |
79 | zeromem(buf, sizeof(buf)); | |
80 | #endif | |
81 | return CRYPT_OK; | |
82 | } | |
83 | ||
84 | /** | |
85 | Self-test the hash | |
86 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled | |
87 | */ | |
88 | int sha384_test(void) | |
89 | { | |
90 | #ifndef LTC_TEST | |
91 | return CRYPT_NOP; | |
92 | #else | |
93 | static const struct { | |
94 | char *msg; | |
95 | unsigned char hash[48]; | |
96 | } tests[] = { | |
97 | { "abc", | |
98 | { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, | |
99 | 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, | |
100 | 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, | |
101 | 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, | |
102 | 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, | |
103 | 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } | |
104 | }, | |
105 | { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", | |
106 | { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, | |
107 | 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, | |
108 | 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, | |
109 | 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, | |
110 | 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, | |
111 | 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } | |
112 | }, | |
113 | }; | |
114 | ||
115 | int i; | |
116 | unsigned char tmp[48]; | |
117 | hash_state md; | |
118 | ||
119 | for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { | |
120 | sha384_init(&md); | |
121 | sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); | |
122 | sha384_done(&md, tmp); | |
123 | if (XMEMCMP(tmp, tests[i].hash, 48) != 0) { | |
124 | return CRYPT_FAIL_TESTVECTOR; | |
125 | } | |
126 | } | |
127 | return CRYPT_OK; | |
128 | #endif | |
129 | } | |
130 | ||
131 | #endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */ | |
132 | ||
133 | /* $Source$ */ | |
134 | /* $Revision$ */ | |
135 | /* $Date$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | /** | |
11 | @param sha384.c | |
12 | LTC_SHA384 hash included in sha512.c, Tom St Denis | |
13 | */ | |
14 | ||
15 | const struct ltc_hash_descriptor sha384_desc = | |
16 | { | |
17 | "sha384", | |
18 | 4, | |
19 | 48, | |
20 | 128, | |
21 | ||
22 | /* OID */ | |
23 | { 2, 16, 840, 1, 101, 3, 4, 2, 2, }, | |
24 | 9, | |
25 | ||
26 | &sha384_init, | |
27 | &sha512_process, | |
28 | &sha384_done, | |
29 | &sha384_test, | |
30 | NULL | |
31 | }; | |
32 | ||
33 | /** | |
34 | Initialize the hash state | |
35 | @param md The hash state you wish to initialize | |
36 | @return CRYPT_OK if successful | |
37 | */ | |
38 | int sha384_init(hash_state * md) | |
39 | { | |
40 | LTC_ARGCHK(md != NULL); | |
41 | ||
42 | md->sha512.curlen = 0; | |
43 | md->sha512.length = 0; | |
44 | md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8); | |
45 | md->sha512.state[1] = CONST64(0x629a292a367cd507); | |
46 | md->sha512.state[2] = CONST64(0x9159015a3070dd17); | |
47 | md->sha512.state[3] = CONST64(0x152fecd8f70e5939); | |
48 | md->sha512.state[4] = CONST64(0x67332667ffc00b31); | |
49 | md->sha512.state[5] = CONST64(0x8eb44a8768581511); | |
50 | md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); | |
51 | md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); | |
52 | return CRYPT_OK; | |
53 | } | |
54 | ||
55 | /** | |
56 | Terminate the hash to get the digest | |
57 | @param md The hash state | |
58 | @param out [out] The destination of the hash (48 bytes) | |
59 | @return CRYPT_OK if successful | |
60 | */ | |
61 | int sha384_done(hash_state * md, unsigned char *out) | |
62 | { | |
63 | unsigned char buf[64]; | |
64 | ||
65 | LTC_ARGCHK(md != NULL); | |
66 | LTC_ARGCHK(out != NULL); | |
67 | ||
68 | if (md->sha512.curlen >= sizeof(md->sha512.buf)) { | |
69 | return CRYPT_INVALID_ARG; | |
70 | } | |
71 | ||
72 | sha512_done(md, buf); | |
73 | XMEMCPY(out, buf, 48); | |
74 | #ifdef LTC_CLEAN_STACK | |
75 | zeromem(buf, sizeof(buf)); | |
76 | #endif | |
77 | return CRYPT_OK; | |
78 | } | |
79 | ||
80 | /** | |
81 | Self-test the hash | |
82 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled | |
83 | */ | |
84 | int sha384_test(void) | |
85 | { | |
86 | #ifndef LTC_TEST | |
87 | return CRYPT_NOP; | |
88 | #else | |
89 | static const struct { | |
90 | char *msg; | |
91 | unsigned char hash[48]; | |
92 | } tests[] = { | |
93 | { "abc", | |
94 | { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, | |
95 | 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, | |
96 | 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, | |
97 | 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, | |
98 | 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, | |
99 | 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } | |
100 | }, | |
101 | { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", | |
102 | { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, | |
103 | 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, | |
104 | 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, | |
105 | 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, | |
106 | 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, | |
107 | 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } | |
108 | }, | |
109 | }; | |
110 | ||
111 | int i; | |
112 | unsigned char tmp[48]; | |
113 | hash_state md; | |
114 | ||
115 | for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { | |
116 | sha384_init(&md); | |
117 | sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); | |
118 | sha384_done(&md, tmp); | |
119 | if (XMEMCMP(tmp, tests[i].hash, 48) != 0) { | |
120 | return CRYPT_FAIL_TESTVECTOR; | |
121 | } | |
122 | } | |
123 | return CRYPT_OK; | |
124 | #endif | |
125 | } | |
126 | ||
127 | ||
128 | ||
129 | ||
130 | ||
131 | ||
132 | /* $Source$ */ | |
133 | /* $Revision$ */ | |
134 | /* $Date$ */ |
304 | 304 | #endif |
305 | 305 | } |
306 | 306 | |
307 | #ifdef LTC_SHA384 | |
308 | #include "sha384.c.inc" | |
309 | #endif | |
310 | ||
311 | 307 | #endif |
312 | 308 | |
313 | 309 |
36 | 36 | }; |
37 | 37 | |
38 | 38 | /* the sboxes */ |
39 | #define __LTC_WHIRLTAB_C__ | |
39 | 40 | #include "whirltab.c.inc" |
40 | 41 | |
41 | 42 | /* get a_{i,j} */ |
74 | 74 | #include <tomcrypt_misc.h> |
75 | 75 | #include <tomcrypt_argchk.h> |
76 | 76 | #include <tomcrypt_pkcs.h> |
77 | #include <tomcrypt_hkdf.h> | |
78 | 77 | |
79 | 78 | #ifdef __cplusplus |
80 | 79 | } |
92 | 92 | #define LTC_FAST_TYPE unsigned long |
93 | 93 | #endif |
94 | 94 | |
95 | /* fix for MSVC ...evil! */ | |
96 | #ifdef _MSC_VER | |
97 | #define CONST64(n) n ## ui64 | |
98 | typedef unsigned __int64 ulong64; | |
99 | #else | |
100 | #define CONST64(n) n ## ULL | |
101 | typedef unsigned long long ulong64; | |
102 | #endif | |
103 | ||
104 | /* this is the "32-bit at least" data type | |
105 | * Re-define it to suit your platform but it must be at least 32-bits | |
106 | */ | |
107 | #if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__)) | |
108 | typedef unsigned ulong32; | |
109 | #else | |
110 | typedef unsigned long ulong32; | |
111 | #endif | |
112 | ||
95 | 113 | /* detect sparc and sparc64 */ |
96 | 114 | #if defined(__sparc__) |
97 | 115 | #define ENDIAN_BIG |
64 | 64 | #endif |
65 | 65 | #define XQSORT qsort |
66 | 66 | #endif |
67 | ||
68 | /* shortcut to disable automatic inclusion */ | |
69 | #if defined LTC_NOTHING && !defined LTC_EASY | |
70 | #define LTC_NO_MATH | |
71 | #define LTC_NO_CIPHERS | |
72 | #define LTC_NO_MODES | |
73 | #define LTC_NO_HASHES | |
74 | #define LTC_NO_MACS | |
75 | #define LTC_NO_PRNGS | |
76 | #define LTC_NO_PK | |
77 | #define LTC_NO_PKCS | |
78 | #define LTC_NO_MISC | |
79 | #endif /* LTC_NOTHING */ | |
67 | 80 | |
68 | 81 | /* Easy button? */ |
69 | 82 | #ifdef LTC_EASY |
99 | 112 | #define LTC_NO_PK |
100 | 113 | #define LTC_MRSA |
101 | 114 | #define LTC_MECC |
102 | #endif | |
103 | ||
104 | /* Use small code where possible */ | |
105 | /* #define LTC_SMALL_CODE */ | |
115 | ||
116 | #define LTC_NO_MISC | |
117 | #define LTC_BASE64 | |
118 | #endif | |
106 | 119 | |
107 | 120 | /* Enable self-test test vector checking */ |
108 | 121 | #ifndef LTC_NO_TEST |
109 | 122 | #define LTC_TEST |
110 | 123 | #endif |
124 | /* Enable extended self-tests */ | |
125 | /* #define LTC_TEST_EXT */ | |
126 | ||
127 | /* Use small code where possible */ | |
128 | /* #define LTC_SMALL_CODE */ | |
111 | 129 | |
112 | 130 | /* clean the stack of functions which put private information on stack */ |
113 | 131 | /* #define LTC_CLEAN_STACK */ |
123 | 141 | |
124 | 142 | /* disable BSWAP on x86 */ |
125 | 143 | /* #define LTC_NO_BSWAP */ |
144 | ||
145 | /* ---> math provider? <--- */ | |
146 | #ifndef LTC_NO_MATH | |
147 | ||
148 | /* LibTomMath */ | |
149 | /* #define LTM_DESC */ | |
150 | ||
151 | /* TomsFastMath */ | |
152 | /* #define TFM_DESC */ | |
153 | ||
154 | #endif /* LTC_NO_MATH */ | |
155 | ||
156 | /* GNU Multiple Precision Arithmetic Library */ | |
157 | /* #define GMP_DESC */ | |
126 | 158 | |
127 | 159 | /* ---> Symmetric Block Ciphers <--- */ |
128 | 160 | #ifndef LTC_NO_CIPHERS |
144 | 176 | #define LTC_TWOFISH_SMALL |
145 | 177 | #endif |
146 | 178 | /* #define LTC_TWOFISH_SMALL */ |
147 | /* LTC_DES includes EDE triple-LTC_DES */ | |
179 | /* LTC_DES includes EDE triple-DES */ | |
148 | 180 | #define LTC_DES |
149 | 181 | #define LTC_CAST5 |
150 | 182 | #define LTC_NOEKEON |
218 | 250 | #define LTC_F9_MODE |
219 | 251 | #define LTC_PELICAN |
220 | 252 | |
221 | #if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) | |
222 | #error Pelican-MAC requires LTC_RIJNDAEL | |
223 | #endif | |
224 | ||
225 | 253 | /* ---> Encrypt + Authenticate Modes <--- */ |
226 | 254 | |
227 | 255 | #define LTC_EAX_MODE |
228 | #if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) | |
229 | #error LTC_EAX_MODE requires CTR and LTC_OMAC mode | |
230 | #endif | |
231 | 256 | |
232 | 257 | #define LTC_OCB_MODE |
233 | 258 | #define LTC_OCB3_MODE |
245 | 270 | #endif |
246 | 271 | |
247 | 272 | #endif /* LTC_NO_MACS */ |
248 | ||
249 | /* Various tidbits of modern neatoness */ | |
250 | #define LTC_BASE64 | |
251 | 273 | |
252 | 274 | /* --> Pseudo Random Number Generators <--- */ |
253 | 275 | #ifndef LTC_NO_PRNGS |
257 | 279 | /* which descriptor of AES to use? */ |
258 | 280 | /* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ |
259 | 281 | #ifdef ENCRYPT_ONLY |
260 | #define LTC_YARROW_AES 3 | |
282 | #define LTC_YARROW_AES 0 | |
261 | 283 | #else |
262 | #define LTC_YARROW_AES 3 | |
263 | #endif | |
264 | ||
265 | #if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) | |
266 | #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! | |
284 | #define LTC_YARROW_AES 2 | |
267 | 285 | #endif |
268 | 286 | |
269 | 287 | /* a PRNG that simply reads from an available system source */ |
289 | 307 | |
290 | 308 | #endif /* LTC_NO_PRNGS */ |
291 | 309 | |
292 | /* ---> math provider? <--- */ | |
293 | #ifndef LTC_NO_MATH | |
294 | ||
295 | /* LibTomMath */ | |
296 | /* #define LTM_DESC */ | |
297 | ||
298 | /* TomsFastMath */ | |
299 | /* #define TFM_DESC */ | |
300 | ||
301 | #endif /* LTC_NO_MATH */ | |
302 | ||
303 | 310 | /* ---> Public Key Crypto <--- */ |
304 | 311 | #ifndef LTC_NO_PK |
305 | 312 | |
306 | 313 | /* Include RSA support */ |
307 | 314 | #define LTC_MRSA |
308 | 315 | |
309 | /* Enable RSA blinding when doing private key operations? */ | |
310 | /* #define LTC_RSA_BLINDING */ | |
316 | #ifndef LTC_NO_RSA_BLINDING | |
317 | /* Enable RSA blinding when doing private key operations by default */ | |
318 | #define LTC_RSA_BLINDING | |
319 | #endif /* LTC_NO_RSA_BLINDING */ | |
311 | 320 | |
312 | 321 | /* Include Diffie-Hellman support */ |
313 | 322 | #ifndef GMP_DESC |
314 | 323 | /* is_prime fails for GMP */ |
315 | #define MDH | |
324 | #define LTC_MDH | |
316 | 325 | /* Supported Key Sizes */ |
317 | 326 | #define DH768 |
318 | 327 | #define DH1024 |
341 | 350 | /* use Shamir's trick for point mul (speeds up signature verification) */ |
342 | 351 | #define LTC_ECC_SHAMIR |
343 | 352 | |
344 | #if defined(TFM_LTC_DESC) && defined(LTC_MECC) | |
353 | #if defined(TFM_DESC) && defined(LTC_MECC) | |
345 | 354 | #define LTC_MECC_ACCEL |
346 | 355 | #endif |
347 | 356 | |
348 | 357 | /* do we want fixed point ECC */ |
349 | 358 | /* #define LTC_MECC_FP */ |
350 | 359 | |
351 | /* Timing Resistant? */ | |
360 | #ifndef LTC_NO_ECC_TIMING_RESISTANT | |
361 | /* Enable ECC timing resistant version by default */ | |
352 | 362 | #define LTC_ECC_TIMING_RESISTANT |
363 | #endif | |
353 | 364 | |
354 | 365 | #endif /* LTC_NO_PK */ |
355 | 366 | |
356 | /* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */ | |
367 | /* PKCS #1 (RSA) and #5 (Password Handling) stuff */ | |
357 | 368 | #ifndef LTC_NO_PKCS |
358 | 369 | |
359 | 370 | #define LTC_PKCS_1 |
364 | 375 | |
365 | 376 | #endif /* LTC_NO_PKCS */ |
366 | 377 | |
367 | /* LTC_HKDF Key Derivation/Expansion stuff */ | |
378 | /* misc stuff */ | |
379 | #ifndef LTC_NO_MISC | |
380 | ||
381 | /* Various tidbits of modern neatoness */ | |
382 | #define LTC_BASE64 | |
383 | /* ... and it's URL safe version */ | |
384 | #define LTC_BASE64_URL | |
385 | ||
386 | /* Keep LTC_NO_HKDF for compatibility reasons | |
387 | * superseeded by LTC_NO_MISC*/ | |
368 | 388 | #ifndef LTC_NO_HKDF |
369 | ||
389 | /* HKDF Key Derivation/Expansion stuff */ | |
370 | 390 | #define LTC_HKDF |
371 | ||
372 | 391 | #endif /* LTC_NO_HKDF */ |
392 | ||
393 | #endif /* LTC_NO_MISC */ | |
373 | 394 | |
374 | 395 | /* cleanup */ |
375 | 396 | |
401 | 422 | #undef LTC_RSA_BLINDING |
402 | 423 | #endif |
403 | 424 | |
425 | #if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) | |
426 | #error Pelican-MAC requires LTC_RIJNDAEL | |
427 | #endif | |
428 | ||
429 | #if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) | |
430 | #error LTC_EAX_MODE requires CTR and LTC_OMAC mode | |
431 | #endif | |
432 | ||
433 | #if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) | |
434 | #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! | |
435 | #endif | |
436 | ||
404 | 437 | #if defined(LTC_DER) && !defined(MPI) |
405 | 438 | #error ASN.1 DER requires MPI functionality |
406 | 439 | #endif |
0 | /* LTC_HKDF Header Info */ | |
1 | ||
2 | /* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */ | |
3 | #ifdef LTC_HKDF | |
4 | ||
5 | int hkdf_test(void); | |
6 | ||
7 | int hkdf_extract(int hash_idx, | |
8 | const unsigned char *salt, unsigned long saltlen, | |
9 | const unsigned char *in, unsigned long inlen, | |
10 | unsigned char *out, unsigned long *outlen); | |
11 | ||
12 | int hkdf_expand(int hash_idx, | |
13 | const unsigned char *info, unsigned long infolen, | |
14 | const unsigned char *in, unsigned long inlen, | |
15 | unsigned char *out, unsigned long outlen); | |
16 | ||
17 | int hkdf(int hash_idx, | |
18 | const unsigned char *salt, unsigned long saltlen, | |
19 | const unsigned char *info, unsigned long infolen, | |
20 | const unsigned char *in, unsigned long inlen, | |
21 | unsigned char *out, unsigned long outlen); | |
22 | ||
23 | #endif /* LTC_HKDF */ | |
24 | ||
25 | /* $Source$ */ | |
26 | /* $Revision$ */ | |
27 | /* $Date$ */ |
0 | /* fix for MSVC ...evil! */ | |
1 | #ifdef _MSC_VER | |
2 | #define CONST64(n) n ## ui64 | |
3 | typedef unsigned __int64 ulong64; | |
4 | #else | |
5 | #define CONST64(n) n ## ULL | |
6 | typedef unsigned long long ulong64; | |
7 | #endif | |
8 | ||
9 | /* this is the "32-bit at least" data type | |
10 | * Re-define it to suit your platform but it must be at least 32-bits | |
11 | */ | |
12 | #if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__)) | |
13 | typedef unsigned ulong32; | |
14 | #else | |
15 | typedef unsigned long ulong32; | |
16 | #endif | |
17 | 0 | |
18 | 1 | /* ---- HELPER MACROS ---- */ |
19 | 2 | #ifdef ENDIAN_NEUTRAL |
20 | 3 | |
21 | 4 | #define STORE32L(x, y) \ |
22 | { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ | |
23 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } | |
5 | do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ | |
6 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) | |
24 | 7 | |
25 | 8 | #define LOAD32L(x, y) \ |
26 | { x = ((unsigned long)((y)[3] & 255)<<24) | \ | |
27 | ((unsigned long)((y)[2] & 255)<<16) | \ | |
28 | ((unsigned long)((y)[1] & 255)<<8) | \ | |
29 | ((unsigned long)((y)[0] & 255)); } | |
9 | do { x = ((ulong32)((y)[3] & 255)<<24) | \ | |
10 | ((ulong32)((y)[2] & 255)<<16) | \ | |
11 | ((ulong32)((y)[1] & 255)<<8) | \ | |
12 | ((ulong32)((y)[0] & 255)); } while(0) | |
30 | 13 | |
31 | 14 | #define STORE64L(x, y) \ |
32 | { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ | |
15 | do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ | |
33 | 16 | (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ |
34 | 17 | (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ |
35 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } | |
18 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) | |
36 | 19 | |
37 | 20 | #define LOAD64L(x, y) \ |
38 | { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ | |
21 | do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ | |
39 | 22 | (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ |
40 | 23 | (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ |
41 | (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } | |
24 | (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) | |
42 | 25 | |
43 | 26 | #define STORE32H(x, y) \ |
44 | { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ | |
45 | (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } | |
27 | do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ | |
28 | (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0) | |
46 | 29 | |
47 | 30 | #define LOAD32H(x, y) \ |
48 | { x = ((unsigned long)((y)[0] & 255)<<24) | \ | |
49 | ((unsigned long)((y)[1] & 255)<<16) | \ | |
50 | ((unsigned long)((y)[2] & 255)<<8) | \ | |
51 | ((unsigned long)((y)[3] & 255)); } | |
31 | do { x = ((ulong32)((y)[0] & 255)<<24) | \ | |
32 | ((ulong32)((y)[1] & 255)<<16) | \ | |
33 | ((ulong32)((y)[2] & 255)<<8) | \ | |
34 | ((ulong32)((y)[3] & 255)); } while(0) | |
52 | 35 | |
53 | 36 | #define STORE64H(x, y) \ |
54 | { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ | |
37 | do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ | |
55 | 38 | (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ |
56 | 39 | (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ |
57 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } | |
40 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) | |
58 | 41 | |
59 | 42 | #define LOAD64H(x, y) \ |
60 | { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ | |
43 | do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ | |
61 | 44 | (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ |
62 | 45 | (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ |
63 | (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } | |
46 | (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0) | |
64 | 47 | |
65 | 48 | #endif /* ENDIAN_NEUTRAL */ |
66 | 49 | |
69 | 52 | #ifdef LTC_HAVE_BSWAP_BUILTIN |
70 | 53 | |
71 | 54 | #define STORE32H(x, y) \ |
72 | { ulong32 __t = __builtin_bswap32 ((x)); \ | |
73 | XMEMCPY ((y), &__t, 4); } | |
55 | do { ulong32 __t = __builtin_bswap32 ((x)); \ | |
56 | XMEMCPY ((y), &__t, 4); } while(0) | |
74 | 57 | |
75 | 58 | #define LOAD32H(x, y) \ |
76 | { XMEMCPY (&(x), (y), 4); \ | |
77 | (x) = __builtin_bswap32 ((x)); } | |
59 | do { XMEMCPY (&(x), (y), 4); \ | |
60 | (x) = __builtin_bswap32 ((x)); } while(0) | |
78 | 61 | |
79 | 62 | #elif !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__)))) |
80 | 63 | |
94 | 77 | #else |
95 | 78 | |
96 | 79 | #define STORE32H(x, y) \ |
97 | { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ | |
98 | (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } | |
80 | do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ | |
81 | (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0) | |
99 | 82 | |
100 | 83 | #define LOAD32H(x, y) \ |
101 | { x = ((unsigned long)((y)[0] & 255)<<24) | \ | |
102 | ((unsigned long)((y)[1] & 255)<<16) | \ | |
103 | ((unsigned long)((y)[2] & 255)<<8) | \ | |
104 | ((unsigned long)((y)[3] & 255)); } | |
84 | do { x = ((ulong32)((y)[0] & 255)<<24) | \ | |
85 | ((ulong32)((y)[1] & 255)<<16) | \ | |
86 | ((ulong32)((y)[2] & 255)<<8) | \ | |
87 | ((ulong32)((y)[3] & 255)); } while(0) | |
105 | 88 | |
106 | 89 | #endif |
107 | 90 | |
108 | 91 | #ifdef LTC_HAVE_BSWAP_BUILTIN |
109 | 92 | |
110 | 93 | #define STORE64H(x, y) \ |
111 | { ulong64 __t = __builtin_bswap64 ((x)); \ | |
112 | XMEMCPY ((y), &__t, 8); } | |
94 | do { ulong64 __t = __builtin_bswap64 ((x)); \ | |
95 | XMEMCPY ((y), &__t, 8); } while(0) | |
113 | 96 | |
114 | 97 | #define LOAD64H(x, y) \ |
115 | { XMEMCPY (&(x), (y), 8); \ | |
116 | (x) = __builtin_bswap64 ((x)); } | |
98 | do { XMEMCPY (&(x), (y), 8); \ | |
99 | (x) = __builtin_bswap64 ((x)); } while(0) | |
117 | 100 | |
118 | 101 | /* x86_64 processor */ |
119 | 102 | #elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) |
134 | 117 | #else |
135 | 118 | |
136 | 119 | #define STORE64H(x, y) \ |
137 | { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ | |
120 | do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ | |
138 | 121 | (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ |
139 | 122 | (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ |
140 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } | |
123 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) | |
141 | 124 | |
142 | 125 | #define LOAD64H(x, y) \ |
143 | { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ | |
126 | do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ | |
144 | 127 | (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ |
145 | 128 | (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ |
146 | (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } | |
129 | (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0) | |
147 | 130 | |
148 | 131 | #endif |
149 | 132 | |
150 | 133 | #ifdef ENDIAN_32BITWORD |
151 | 134 | |
152 | 135 | #define STORE32L(x, y) \ |
153 | { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } | |
136 | do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) | |
154 | 137 | |
155 | 138 | #define LOAD32L(x, y) \ |
156 | XMEMCPY(&(x), y, 4); | |
139 | do { XMEMCPY(&(x), y, 4); } while(0) | |
157 | 140 | |
158 | 141 | #define STORE64L(x, y) \ |
159 | { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ | |
142 | do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ | |
160 | 143 | (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ |
161 | 144 | (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ |
162 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } | |
145 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) | |
163 | 146 | |
164 | 147 | #define LOAD64L(x, y) \ |
165 | { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ | |
148 | do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ | |
166 | 149 | (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ |
167 | 150 | (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ |
168 | (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } | |
151 | (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) | |
169 | 152 | |
170 | 153 | #else /* 64-bit words then */ |
171 | 154 | |
172 | 155 | #define STORE32L(x, y) \ |
173 | { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } | |
156 | do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) | |
174 | 157 | |
175 | 158 | #define LOAD32L(x, y) \ |
176 | { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } | |
159 | do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0) | |
177 | 160 | |
178 | 161 | #define STORE64L(x, y) \ |
179 | { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } | |
162 | do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0) | |
180 | 163 | |
181 | 164 | #define LOAD64L(x, y) \ |
182 | { XMEMCPY(&(x), y, 8); } | |
165 | do { XMEMCPY(&(x), y, 8); } while(0) | |
183 | 166 | |
184 | 167 | #endif /* ENDIAN_64BITWORD */ |
185 | 168 | |
187 | 170 | |
188 | 171 | #ifdef ENDIAN_BIG |
189 | 172 | #define STORE32L(x, y) \ |
190 | { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ | |
191 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } | |
173 | do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ | |
174 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) | |
192 | 175 | |
193 | 176 | #define LOAD32L(x, y) \ |
194 | { x = ((unsigned long)((y)[3] & 255)<<24) | \ | |
195 | ((unsigned long)((y)[2] & 255)<<16) | \ | |
196 | ((unsigned long)((y)[1] & 255)<<8) | \ | |
197 | ((unsigned long)((y)[0] & 255)); } | |
177 | do { x = ((ulong32)((y)[3] & 255)<<24) | \ | |
178 | ((ulong32)((y)[2] & 255)<<16) | \ | |
179 | ((ulong32)((y)[1] & 255)<<8) | \ | |
180 | ((ulong32)((y)[0] & 255)); } while(0) | |
198 | 181 | |
199 | 182 | #define STORE64L(x, y) \ |
200 | { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ | |
183 | do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ | |
201 | 184 | (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ |
202 | 185 | (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ |
203 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } | |
186 | (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) | |
204 | 187 | |
205 | 188 | #define LOAD64L(x, y) \ |
206 | { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ | |
189 | do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ | |
207 | 190 | (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ |
208 | 191 | (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ |
209 | (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } | |
192 | (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) | |
210 | 193 | |
211 | 194 | #ifdef ENDIAN_32BITWORD |
212 | 195 | |
213 | 196 | #define STORE32H(x, y) \ |
214 | { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } | |
197 | do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) | |
215 | 198 | |
216 | 199 | #define LOAD32H(x, y) \ |
217 | XMEMCPY(&(x), y, 4); | |
200 | do { XMEMCPY(&(x), y, 4); } while(0) | |
218 | 201 | |
219 | 202 | #define STORE64H(x, y) \ |
220 | { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ | |
203 | do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ | |
221 | 204 | (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ |
222 | 205 | (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ |
223 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } | |
206 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) | |
224 | 207 | |
225 | 208 | #define LOAD64H(x, y) \ |
226 | { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ | |
209 | do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ | |
227 | 210 | (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ |
228 | 211 | (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ |
229 | (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } | |
212 | (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } while(0) | |
230 | 213 | |
231 | 214 | #else /* 64-bit words then */ |
232 | 215 | |
233 | 216 | #define STORE32H(x, y) \ |
234 | { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } | |
217 | do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) | |
235 | 218 | |
236 | 219 | #define LOAD32H(x, y) \ |
237 | { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } | |
220 | do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0) | |
238 | 221 | |
239 | 222 | #define STORE64H(x, y) \ |
240 | { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } | |
223 | do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0) | |
241 | 224 | |
242 | 225 | #define LOAD64H(x, y) \ |
243 | { XMEMCPY(&(x), y, 8); } | |
226 | do { XMEMCPY(&(x), y, 8); } while(0) | |
244 | 227 | |
245 | 228 | #endif /* ENDIAN_64BITWORD */ |
246 | 229 | #endif /* ENDIAN_BIG */ |
350 | 333 | #else |
351 | 334 | |
352 | 335 | /* rotates the hard way */ |
353 | #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
354 | #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
355 | #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
356 | #define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
336 | #define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
337 | #define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
338 | #define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
339 | #define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
357 | 340 | |
358 | 341 | #endif |
359 | 342 |
4 | 4 | |
5 | 5 | int base64_decode(const unsigned char *in, unsigned long len, |
6 | 6 | unsigned char *out, unsigned long *outlen); |
7 | #endif | |
7 | 8 | |
9 | #ifdef LTC_BASE64_URL | |
8 | 10 | int base64url_encode(const unsigned char *in, unsigned long len, |
9 | 11 | unsigned char *out, unsigned long *outlen); |
10 | 12 | |
11 | 13 | int base64url_decode(const unsigned char *in, unsigned long len, |
12 | 14 | unsigned char *out, unsigned long *outlen); |
13 | 15 | #endif |
16 | ||
17 | /* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */ | |
18 | #ifdef LTC_HKDF | |
19 | ||
20 | int hkdf_test(void); | |
21 | ||
22 | int hkdf_extract(int hash_idx, | |
23 | const unsigned char *salt, unsigned long saltlen, | |
24 | const unsigned char *in, unsigned long inlen, | |
25 | unsigned char *out, unsigned long *outlen); | |
26 | ||
27 | int hkdf_expand(int hash_idx, | |
28 | const unsigned char *info, unsigned long infolen, | |
29 | const unsigned char *in, unsigned long inlen, | |
30 | unsigned char *out, unsigned long outlen); | |
31 | ||
32 | int hkdf(int hash_idx, | |
33 | const unsigned char *salt, unsigned long saltlen, | |
34 | const unsigned char *info, unsigned long infolen, | |
35 | const unsigned char *in, unsigned long inlen, | |
36 | unsigned char *out, unsigned long outlen); | |
37 | ||
38 | #endif /* LTC_HKDF */ | |
14 | 39 | |
15 | 40 | /* ---- MEM routines ---- */ |
16 | 41 | void zeromem(volatile void *dst, size_t len); |
37 | 37 | #define MIN_RSA_SIZE 1024 |
38 | 38 | #define MAX_RSA_SIZE 4096 |
39 | 39 | |
40 | /** RSA LTC_PKCS style key */ | |
40 | /** RSA PKCS style key */ | |
41 | 41 | typedef struct Rsa_key { |
42 | 42 | /** Type of key, PK_PRIVATE or PK_PUBLIC */ |
43 | 43 | int type; |
61 | 61 | |
62 | 62 | int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); |
63 | 63 | |
64 | int rsa_get_size(rsa_key *key); | |
65 | ||
64 | 66 | int rsa_exptmod(const unsigned char *in, unsigned long inlen, |
65 | 67 | unsigned char *out, unsigned long *outlen, int which, |
66 | 68 | rsa_key *key); |
67 | 69 | |
68 | 70 | void rsa_free(rsa_key *key); |
69 | 71 | |
70 | /* These use LTC_PKCS #1 v2.0 padding */ | |
72 | /* These use PKCS #1 v2.0 padding */ | |
71 | 73 | #define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ |
72 | 74 | rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_PKCS_1_OAEP, _key) |
73 | 75 | |
80 | 82 | #define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ |
81 | 83 | rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) |
82 | 84 | |
83 | /* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */ | |
85 | #define rsa_sign_saltlen_get_max(_hash_idx, _key) \ | |
86 | rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, _hash_idx, _key) | |
87 | ||
88 | /* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */ | |
84 | 89 | int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, |
85 | 90 | unsigned char *out, unsigned long *outlen, |
86 | 91 | const unsigned char *lparam, unsigned long lparamlen, |
105 | 110 | int hash_idx, unsigned long saltlen, |
106 | 111 | int *stat, rsa_key *key); |
107 | 112 | |
108 | /* LTC_PKCS #1 import/export */ | |
113 | int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, rsa_key *key); | |
114 | ||
115 | /* PKCS #1 import/export */ | |
109 | 116 | int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); |
110 | 117 | int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); |
111 | 118 | |
118 | 125 | #define MIN_KAT_SIZE 1024 |
119 | 126 | #define MAX_KAT_SIZE 4096 |
120 | 127 | |
121 | /** Katja LTC_PKCS style key */ | |
128 | /** Katja PKCS style key */ | |
122 | 129 | typedef struct KAT_key { |
123 | 130 | /** Type of key, PK_PRIVATE or PK_PUBLIC */ |
124 | 131 | int type; |
148 | 155 | |
149 | 156 | void katja_free(katja_key *key); |
150 | 157 | |
151 | /* These use LTC_PKCS #1 v2.0 padding */ | |
158 | /* These use PKCS #1 v2.0 padding */ | |
152 | 159 | int katja_encrypt_key(const unsigned char *in, unsigned long inlen, |
153 | 160 | unsigned char *out, unsigned long *outlen, |
154 | 161 | const unsigned char *lparam, unsigned long lparamlen, |
160 | 167 | int hash_idx, int *stat, |
161 | 168 | katja_key *key); |
162 | 169 | |
163 | /* LTC_PKCS #1 import/export */ | |
170 | /* PKCS #1 import/export */ | |
164 | 171 | int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); |
165 | 172 | int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); |
166 | 173 | |
167 | 174 | #endif |
168 | 175 | |
169 | 176 | /* ---- DH Routines ---- */ |
170 | #ifdef MDH | |
177 | #ifdef LTC_MDH | |
171 | 178 | |
172 | 179 | typedef struct Dh_key { |
173 | 180 | int idx, type; |
338 | 345 | int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y); |
339 | 346 | |
340 | 347 | /* point ops (mp == montgomery digit) */ |
341 | #if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC) | |
348 | #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) | |
342 | 349 | /* R = 2P */ |
343 | 350 | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp); |
344 | 351 | |
519 | 526 | |
520 | 527 | #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) |
521 | 528 | |
522 | int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen); | |
523 | int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen, unsigned long *payloadlen); | |
529 | int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, | |
530 | unsigned long *outlen); | |
531 | int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, | |
532 | unsigned long *outlen, unsigned long *payloadlen); | |
524 | 533 | |
525 | 534 | /* SUBJECT PUBLIC KEY INFO */ |
526 | 535 | int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, |
0 | /* LTC_PKCS Header Info */ | |
0 | /* PKCS Header Info */ | |
1 | 1 | |
2 | /* ===> LTC_PKCS #1 -- RSA Cryptography <=== */ | |
2 | /* ===> PKCS #1 -- RSA Cryptography <=== */ | |
3 | 3 | #ifdef LTC_PKCS_1 |
4 | 4 | |
5 | 5 | enum ltc_pkcs_1_v1_5_blocks |
6 | 6 | { |
7 | LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */ | |
8 | LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */ | |
7 | LTC_PKCS_1_EMSA = 1, /* Block type 1 (PKCS #1 v1.5 signature padding) */ | |
8 | LTC_PKCS_1_EME = 2 /* Block type 2 (PKCS #1 v1.5 encryption padding) */ | |
9 | 9 | }; |
10 | 10 | |
11 | 11 | enum ltc_pkcs_1_paddings |
12 | 12 | { |
13 | LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ | |
14 | LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */ | |
15 | LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */ | |
13 | LTC_PKCS_1_V1_5 = 1, /* PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ | |
14 | LTC_PKCS_1_OAEP = 2, /* PKCS #1 v2.0 encryption padding */ | |
15 | LTC_PKCS_1_PSS = 3 /* PKCS #1 v2.1 signature padding */ | |
16 | 16 | }; |
17 | 17 | |
18 | 18 | int pkcs_1_mgf1( int hash_idx, |
66 | 66 | |
67 | 67 | #endif /* LTC_PKCS_1 */ |
68 | 68 | |
69 | /* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */ | |
69 | /* ===> PKCS #5 -- Password Based Cryptography <=== */ | |
70 | 70 | #ifdef LTC_PKCS_5 |
71 | 71 | |
72 | 72 | /* Algorithm #1 (old) */ |
81 | 81 | int iteration_count, int hash_idx, |
82 | 82 | unsigned char *out, unsigned long *outlen); |
83 | 83 | |
84 | int pkcs_5_test (void); | |
84 | 85 | #endif /* LTC_PKCS_5 */ |
85 | 86 | |
86 | 87 | /* $Source$ */ |
66 | 66 | f9->IV[f9->buflen++] ^= *in++; |
67 | 67 | --inlen; |
68 | 68 | } |
69 | return CRYPT_OK; | |
69 | return CRYPT_OK; | |
70 | 70 | } |
71 | 71 | |
72 | 72 | #endif |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file hmac_done.c |
14 | LTC_HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer | |
14 | HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_HMAC |
19 | 19 | #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize |
20 | 20 | |
21 | 21 | /** |
22 | Terminate an LTC_HMAC session | |
23 | @param hmac The LTC_HMAC state | |
24 | @param out [out] The destination of the LTC_HMAC authentication tag | |
25 | @param outlen [in/out] The max size and resulting size of the LTC_HMAC authentication tag | |
22 | Terminate an HMAC session | |
23 | @param hmac The HMAC state | |
24 | @param out [out] The destination of the HMAC authentication tag | |
25 | @param outlen [in/out] The max size and resulting size of the HMAC authentication tag | |
26 | 26 | @return CRYPT_OK if successful |
27 | 27 | */ |
28 | 28 | int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen) |
46 | 46 | /* allocate buffers */ |
47 | 47 | buf = XMALLOC(LTC_HMAC_BLOCKSIZE); |
48 | 48 | isha = XMALLOC(hashsize); |
49 | if (buf == NULL || isha == NULL) { | |
49 | if (buf == NULL || isha == NULL) { | |
50 | 50 | if (buf != NULL) { |
51 | 51 | XFREE(buf); |
52 | } | |
52 | } | |
53 | 53 | if (isha != NULL) { |
54 | 54 | XFREE(isha); |
55 | } | |
55 | } | |
56 | 56 | return CRYPT_MEM; |
57 | 57 | } |
58 | 58 | |
59 | /* Get the hash of the first LTC_HMAC vector plus the data */ | |
59 | /* Get the hash of the first HMAC vector plus the data */ | |
60 | 60 | if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) { |
61 | 61 | goto LBL_ERR; |
62 | 62 | } |
63 | 63 | |
64 | /* Create the second LTC_HMAC vector vector for step (3) */ | |
64 | /* Create the second HMAC vector vector for step (3) */ | |
65 | 65 | for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { |
66 | 66 | buf[i] = hmac->key[i] ^ 0x5C; |
67 | 67 | } |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file hmac_file.c |
14 | LTC_HMAC support, process a file, Tom St Denis/Dobes Vandermeer | |
14 | HMAC support, process a file, Tom St Denis/Dobes Vandermeer | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_HMAC |
18 | 18 | |
19 | 19 | /** |
20 | LTC_HMAC a file | |
20 | HMAC a file | |
21 | 21 | @param hash The index of the hash you wish to use |
22 | @param fname The name of the file you wish to LTC_HMAC | |
22 | @param fname The name of the file you wish to HMAC | |
23 | 23 | @param key The secret key |
24 | 24 | @param keylen The length of the secret key |
25 | @param out [out] The LTC_HMAC authentication tag | |
25 | @param out [out] The HMAC authentication tag | |
26 | 26 | @param outlen [in/out] The max size and resulting size of the authentication tag |
27 | 27 | @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled |
28 | 28 | */ |
29 | int hmac_file(int hash, const char *fname, | |
30 | const unsigned char *key, unsigned long keylen, | |
29 | int hmac_file(int hash, const char *fname, | |
30 | const unsigned char *key, unsigned long keylen, | |
31 | 31 | unsigned char *out, unsigned long *outlen) |
32 | 32 | { |
33 | 33 | #ifdef LTC_NO_FILE |
43 | 43 | LTC_ARGCHK(key != NULL); |
44 | 44 | LTC_ARGCHK(out != NULL); |
45 | 45 | LTC_ARGCHK(outlen != NULL); |
46 | ||
46 | ||
47 | 47 | if((err = hash_is_valid(hash)) != CRYPT_OK) { |
48 | 48 | return err; |
49 | 49 | } |
79 | 79 | #ifdef LTC_CLEAN_STACK |
80 | 80 | /* clear memory */ |
81 | 81 | zeromem(buf, sizeof(buf)); |
82 | #endif | |
82 | #endif | |
83 | 83 | return CRYPT_OK; |
84 | 84 | #endif |
85 | 85 | } |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file hmac_init.c |
14 | LTC_HMAC support, initialize state, Tom St Denis/Dobes Vandermeer | |
14 | HMAC support, initialize state, Tom St Denis/Dobes Vandermeer | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_HMAC |
19 | 19 | #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize |
20 | 20 | |
21 | 21 | /** |
22 | Initialize an LTC_HMAC context. | |
23 | @param hmac The LTC_HMAC state | |
24 | @param hash The index of the hash you want to use | |
22 | Initialize an HMAC context. | |
23 | @param hmac The HMAC state | |
24 | @param hash The index of the hash you want to use | |
25 | 25 | @param key The secret key |
26 | 26 | @param keylen The length of the secret key (octets) |
27 | 27 | @return CRYPT_OK if successful |
99 | 99 | #ifdef LTC_CLEAN_STACK |
100 | 100 | zeromem(buf, LTC_HMAC_BLOCKSIZE); |
101 | 101 | #endif |
102 | ||
102 | ||
103 | 103 | XFREE(buf); |
104 | return err; | |
104 | return err; | |
105 | 105 | } |
106 | 106 | |
107 | 107 | #endif |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file hmac_memory.c |
14 | LTC_HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer | |
14 | HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_HMAC |
18 | 18 | |
19 | 19 | /** |
20 | LTC_HMAC a block of memory to produce the authentication tag | |
21 | @param hash The index of the hash to use | |
22 | @param key The secret key | |
20 | HMAC a block of memory to produce the authentication tag | |
21 | @param hash The index of the hash to use | |
22 | @param key The secret key | |
23 | 23 | @param keylen The length of the secret key (octets) |
24 | @param in The data to LTC_HMAC | |
25 | @param inlen The length of the data to LTC_HMAC (octets) | |
24 | @param in The data to HMAC | |
25 | @param inlen The length of the data to HMAC (octets) | |
26 | 26 | @param out [out] Destination of the authentication tag |
27 | 27 | @param outlen [in/out] Max size and resulting size of authentication tag |
28 | 28 | @return CRYPT_OK if successful |
29 | 29 | */ |
30 | int hmac_memory(int hash, | |
30 | int hmac_memory(int hash, | |
31 | 31 | const unsigned char *key, unsigned long keylen, |
32 | const unsigned char *in, unsigned long inlen, | |
32 | const unsigned char *in, unsigned long inlen, | |
33 | 33 | unsigned char *out, unsigned long *outlen) |
34 | 34 | { |
35 | 35 | hmac_state *hmac; |
37 | 37 | |
38 | 38 | LTC_ARGCHK(key != NULL); |
39 | 39 | LTC_ARGCHK(in != NULL); |
40 | LTC_ARGCHK(out != NULL); | |
40 | LTC_ARGCHK(out != NULL); | |
41 | 41 | LTC_ARGCHK(outlen != NULL); |
42 | 42 | |
43 | 43 | /* make sure hash descriptor is valid */ |
76 | 76 | #endif |
77 | 77 | |
78 | 78 | XFREE(hmac); |
79 | return err; | |
79 | return err; | |
80 | 80 | } |
81 | 81 | |
82 | 82 | #endif |
12 | 12 | |
13 | 13 | /** |
14 | 14 | @file hmac_memory_multi.c |
15 | LTC_HMAC support, process multiple blocks of memory, Tom St Denis/Dobes Vandermeer | |
15 | HMAC support, process multiple blocks of memory, Tom St Denis/Dobes Vandermeer | |
16 | 16 | */ |
17 | 17 | |
18 | 18 | #ifdef LTC_HMAC |
19 | 19 | |
20 | 20 | /** |
21 | LTC_HMAC multiple blocks of memory to produce the authentication tag | |
22 | @param hash The index of the hash to use | |
23 | @param key The secret key | |
21 | HMAC multiple blocks of memory to produce the authentication tag | |
22 | @param hash The index of the hash to use | |
23 | @param key The secret key | |
24 | 24 | @param keylen The length of the secret key (octets) |
25 | 25 | @param out [out] Destination of the authentication tag |
26 | 26 | @param outlen [in/out] Max size and resulting size of authentication tag |
27 | @param in The data to LTC_HMAC | |
28 | @param inlen The length of the data to LTC_HMAC (octets) | |
29 | @param ... tuples of (data,len) pairs to LTC_HMAC, terminated with a (NULL,x) (x=don't care) | |
27 | @param in The data to HMAC | |
28 | @param inlen The length of the data to HMAC (octets) | |
29 | @param ... tuples of (data,len) pairs to HMAC, terminated with a (NULL,x) (x=don't care) | |
30 | 30 | @return CRYPT_OK if successful |
31 | 31 | */ |
32 | int hmac_memory_multi(int hash, | |
32 | int hmac_memory_multi(int hash, | |
33 | 33 | const unsigned char *key, unsigned long keylen, |
34 | 34 | unsigned char *out, unsigned long *outlen, |
35 | 35 | const unsigned char *in, unsigned long inlen, ...) |
43 | 43 | |
44 | 44 | LTC_ARGCHK(key != NULL); |
45 | 45 | LTC_ARGCHK(in != NULL); |
46 | LTC_ARGCHK(out != NULL); | |
46 | LTC_ARGCHK(out != NULL); | |
47 | 47 | LTC_ARGCHK(outlen != NULL); |
48 | 48 | |
49 | 49 | /* allocate ram for hmac state */ |
57 | 57 | } |
58 | 58 | |
59 | 59 | va_start(args, inlen); |
60 | curptr = in; | |
60 | curptr = in; | |
61 | 61 | curlen = inlen; |
62 | 62 | for (;;) { |
63 | 63 | /* process buf */ |
80 | 80 | #endif |
81 | 81 | XFREE(hmac); |
82 | 82 | va_end(args); |
83 | return err; | |
83 | return err; | |
84 | 84 | } |
85 | 85 | |
86 | 86 | #endif |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file hmac_process.c |
14 | LTC_HMAC support, process data, Tom St Denis/Dobes Vandermeer | |
14 | HMAC support, process data, Tom St Denis/Dobes Vandermeer | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_HMAC |
18 | 18 | |
19 | /** | |
20 | Process data through LTC_HMAC | |
19 | /** | |
20 | Process data through HMAC | |
21 | 21 | @param hmac The hmac state |
22 | @param in The data to send through LTC_HMAC | |
23 | @param inlen The length of the data to LTC_HMAC (octets) | |
22 | @param in The data to send through HMAC | |
23 | @param inlen The length of the data to HMAC (octets) | |
24 | 24 | @return CRYPT_OK if successful |
25 | 25 | */ |
26 | 26 | int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen) |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file omac_done.c |
14 | LTC_OMAC1 support, terminate a stream, Tom St Denis | |
14 | OMAC1 support, terminate a stream, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_OMAC |
18 | 18 | |
19 | 19 | /** |
20 | Terminate an LTC_OMAC stream | |
21 | @param omac The LTC_OMAC state | |
20 | Terminate an OMAC stream | |
21 | @param omac The OMAC state | |
22 | 22 | @param out [out] Destination for the authentication tag |
23 | 23 | @param outlen [in/out] The max size and resulting size of the authentication tag |
24 | 24 | @return CRYPT_OK if successful |
64 | 64 | return err; |
65 | 65 | } |
66 | 66 | cipher_descriptor[omac->cipher_idx].done(&omac->key); |
67 | ||
67 | ||
68 | 68 | /* output it */ |
69 | 69 | for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) { |
70 | 70 | out[x] = omac->block[x]; |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file omac_file.c |
14 | LTC_OMAC1 support, process a file, Tom St Denis | |
14 | OMAC1 support, process a file, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_OMAC |
18 | 18 | |
19 | 19 | /** |
20 | LTC_OMAC a file | |
20 | OMAC a file | |
21 | 21 | @param cipher The index of the cipher desired |
22 | 22 | @param key The secret key |
23 | 23 | @param keylen The length of the secret key (octets) |
24 | @param filename The name of the file you wish to LTC_OMAC | |
24 | @param filename The name of the file you wish to OMAC | |
25 | 25 | @param out [out] Where the authentication tag is to be stored |
26 | 26 | @param outlen [in/out] The max size and resulting size of the authentication tag |
27 | 27 | @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled |
28 | 28 | */ |
29 | int omac_file(int cipher, | |
29 | int omac_file(int cipher, | |
30 | 30 | const unsigned char *key, unsigned long keylen, |
31 | const char *filename, | |
31 | const char *filename, | |
32 | 32 | unsigned char *out, unsigned long *outlen) |
33 | 33 | { |
34 | 34 | #ifdef LTC_NO_FILE |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file omac_init.c |
14 | LTC_OMAC1 support, initialize state, by Tom St Denis | |
14 | OMAC1 support, initialize state, by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | |
18 | 18 | #ifdef LTC_OMAC |
19 | 19 | |
20 | 20 | /** |
21 | Initialize an LTC_OMAC state | |
22 | @param omac The LTC_OMAC state to initialize | |
21 | Initialize an OMAC state | |
22 | @param omac The OMAC state to initialize | |
23 | 23 | @param cipher The index of the desired cipher |
24 | 24 | @param key The secret key |
25 | 25 | @param keylen The length of the secret key (octets) |
76 | 76 | omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255; |
77 | 77 | } |
78 | 78 | omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255; |
79 | ||
79 | ||
80 | 80 | /* copy up as require */ |
81 | 81 | if (x == 0) { |
82 | 82 | XMEMCPY(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0])); |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file omac_memory.c |
14 | LTC_OMAC1 support, process a block of memory, Tom St Denis | |
14 | OMAC1 support, process a block of memory, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_OMAC |
18 | 18 | |
19 | 19 | /** |
20 | LTC_OMAC a block of memory | |
20 | OMAC a block of memory | |
21 | 21 | @param cipher The index of the desired cipher |
22 | 22 | @param key The secret key |
23 | 23 | @param keylen The length of the secret key (octets) |
24 | @param in The data to send through LTC_OMAC | |
25 | @param inlen The length of the data to send through LTC_OMAC (octets) | |
24 | @param in The data to send through OMAC | |
25 | @param inlen The length of the data to send through OMAC (octets) | |
26 | 26 | @param out [out] The destination of the authentication tag |
27 | 27 | @param outlen [in/out] The max size and resulting size of the authentication tag (octets) |
28 | 28 | @return CRYPT_OK if successful |
29 | 29 | */ |
30 | int omac_memory(int cipher, | |
30 | int omac_memory(int cipher, | |
31 | 31 | const unsigned char *key, unsigned long keylen, |
32 | 32 | const unsigned char *in, unsigned long inlen, |
33 | 33 | unsigned char *out, unsigned long *outlen) |
74 | 74 | #endif |
75 | 75 | |
76 | 76 | XFREE(omac); |
77 | return err; | |
77 | return err; | |
78 | 78 | } |
79 | 79 | |
80 | 80 | #endif |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | #include <stdarg.h> |
12 | 12 | |
13 | /** | |
13 | /** | |
14 | 14 | @file omac_memory_multi.c |
15 | LTC_OMAC1 support, process multiple blocks of memory, Tom St Denis | |
15 | OMAC1 support, process multiple blocks of memory, Tom St Denis | |
16 | 16 | */ |
17 | 17 | |
18 | 18 | #ifdef LTC_OMAC |
19 | 19 | |
20 | 20 | /** |
21 | LTC_OMAC multiple blocks of memory | |
21 | OMAC multiple blocks of memory | |
22 | 22 | @param cipher The index of the desired cipher |
23 | 23 | @param key The secret key |
24 | 24 | @param keylen The length of the secret key (octets) |
25 | 25 | @param out [out] The destination of the authentication tag |
26 | 26 | @param outlen [in/out] The max size and resulting size of the authentication tag (octets) |
27 | @param in The data to send through LTC_OMAC | |
28 | @param inlen The length of the data to send through LTC_OMAC (octets) | |
29 | @param ... tuples of (data,len) pairs to LTC_OMAC, terminated with a (NULL,x) (x=don't care) | |
27 | @param in The data to send through OMAC | |
28 | @param inlen The length of the data to send through OMAC (octets) | |
29 | @param ... tuples of (data,len) pairs to OMAC, terminated with a (NULL,x) (x=don't care) | |
30 | 30 | @return CRYPT_OK if successful |
31 | 31 | */ |
32 | int omac_memory_multi(int cipher, | |
32 | int omac_memory_multi(int cipher, | |
33 | 33 | const unsigned char *key, unsigned long keylen, |
34 | 34 | unsigned char *out, unsigned long *outlen, |
35 | 35 | const unsigned char *in, unsigned long inlen, ...) |
56 | 56 | goto LBL_ERR; |
57 | 57 | } |
58 | 58 | va_start(args, inlen); |
59 | curptr = in; | |
59 | curptr = in; | |
60 | 60 | curlen = inlen; |
61 | 61 | for (;;) { |
62 | 62 | /* process buf */ |
79 | 79 | #endif |
80 | 80 | XFREE(omac); |
81 | 81 | va_end(args); |
82 | return err; | |
82 | return err; | |
83 | 83 | } |
84 | 84 | |
85 | 85 | #endif |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file omac_process.c |
14 | LTC_OMAC1 support, process data, Tom St Denis | |
14 | OMAC1 support, process data, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | |
18 | 18 | #ifdef LTC_OMAC |
19 | 19 | |
20 | /** | |
21 | Process data through LTC_OMAC | |
22 | @param omac The LTC_OMAC state | |
23 | @param in The input data to send through LTC_OMAC | |
20 | /** | |
21 | Process data through OMAC | |
22 | @param omac The OMAC state | |
23 | @param in The input data to send through OMAC | |
24 | 24 | @param inlen The length of the input (octets) |
25 | 25 | @return CRYPT_OK if successful |
26 | 26 | */ |
42 | 42 | |
43 | 43 | #ifdef LTC_FAST |
44 | 44 | { |
45 | unsigned long blklen; | |
46 | ||
47 | blklen = cipher_descriptor[omac->cipher_idx].block_length; | |
48 | if (omac->buflen == 0 && inlen > blklen) { | |
49 | unsigned long y; | |
50 | for (x = 0; x < (inlen - blklen); x += blklen) { | |
51 | for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) { | |
52 | *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y])); | |
53 | } | |
54 | in += blklen; | |
55 | if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { | |
56 | return err; | |
57 | } | |
58 | } | |
59 | inlen -= x; | |
45 | unsigned long blklen = cipher_descriptor[omac->cipher_idx].block_length; | |
46 | ||
47 | if (omac->buflen == 0 && inlen > blklen) { | |
48 | unsigned long y; | |
49 | for (x = 0; x < (inlen - blklen); x += blklen) { | |
50 | for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) { | |
51 | *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y])); | |
52 | } | |
53 | in += blklen; | |
54 | if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { | |
55 | return err; | |
56 | } | |
60 | 57 | } |
58 | inlen -= x; | |
59 | } | |
61 | 60 | } |
62 | 61 | #endif |
63 | 62 | |
64 | while (inlen != 0) { | |
63 | while (inlen != 0) { | |
65 | 64 | /* ok if the block is full we xor in prev, encrypt and replace prev */ |
66 | 65 | if (omac->buflen == omac->blklen) { |
67 | 66 | for (x = 0; x < (unsigned long)omac->blklen; x++) { |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pelican.c |
14 | Pelican MAC, initialize state, by Tom St Denis | |
14 | Pelican MAC, initialize state, by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PELICAN |
18 | 18 | |
19 | #define __LTC_AES_TAB_C__ | |
19 | 20 | #define ENCRYPT_ONLY |
20 | 21 | #define PELI_TAB |
21 | 22 | #include "../../ciphers/aes/aes_tab.c.inc" |
23 | 24 | /** |
24 | 25 | Initialize a Pelican state |
25 | 26 | @param pelmac The Pelican state to initialize |
26 | @param key The secret key | |
27 | @param key The secret key | |
27 | 28 | @param keylen The length of the secret key (octets) |
28 | 29 | @return CRYPT_OK if successful |
29 | 30 | */ |
30 | 31 | int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen) |
31 | 32 | { |
32 | 33 | int err; |
33 | ||
34 | ||
34 | 35 | LTC_ARGCHK(pelmac != NULL); |
35 | 36 | LTC_ARGCHK(key != NULL); |
36 | 37 | |
48 | 49 | aes_ecb_encrypt(pelmac->state, pelmac->state, &pelmac->K); |
49 | 50 | pelmac->buflen = 0; |
50 | 51 | |
51 | return CRYPT_OK; | |
52 | return CRYPT_OK; | |
52 | 53 | } |
53 | 54 | |
54 | 55 | static void four_rounds(pelican_state *pelmac) |
89 | 90 | STORE32H(s3, pelmac->state + 12); |
90 | 91 | } |
91 | 92 | |
92 | /** | |
93 | /** | |
93 | 94 | Process a block of text through Pelican |
94 | 95 | @param pelmac The Pelican MAC state |
95 | 96 | @param in The input |
155 | 156 | aes_ecb_encrypt(pelmac->state, out, &pelmac->K); |
156 | 157 | aes_done(&pelmac->K); |
157 | 158 | return CRYPT_OK; |
158 | } | |
159 | } | |
159 | 160 | |
160 | 161 | #endif |
161 | 162 |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pmac_process.c |
14 | PMAC implementation, process data, by Tom St Denis | |
14 | PMAC implementation, process data, by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | |
61 | 61 | } |
62 | 62 | #endif |
63 | 63 | |
64 | while (inlen != 0) { | |
64 | while (inlen != 0) { | |
65 | 65 | /* ok if the block is full we xor in prev, encrypt and replace prev */ |
66 | 66 | if (pmac->buflen == pmac->block_len) { |
67 | 67 | pmac_shift_xor(pmac); |
63 | 63 | xcbc->IV[xcbc->buflen++] ^= *in++; |
64 | 64 | --inlen; |
65 | 65 | } |
66 | return CRYPT_OK; | |
66 | return CRYPT_OK; | |
67 | 67 | } |
68 | 68 | |
69 | 69 | #endif |
43 | 43 | |
44 | 44 | cleanup: |
45 | 45 | #ifdef LTC_CLEAN_STACK |
46 | zeromem(buf, len); | |
46 | zeromem(buf, bytes); | |
47 | 47 | #endif |
48 | 48 | XFREE(buf); |
49 | 49 | return res; |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | #if !defined LTC_NO_MATH && !defined LTC_NO_PRNGS | |
13 | ||
12 | 14 | /** |
13 | 15 | @file rand_prime.c |
14 | 16 | Generate a random prime, Tom St Denis |
15 | */ | |
17 | */ | |
16 | 18 | |
17 | 19 | #define USE_BBS 1 |
18 | ||
19 | int rand_helper(unsigned char *dst, int len, void *dat) | |
20 | { | |
21 | return (int)prng_descriptor[((rand_helper_st *)dat)->wprng].read(dst, len, ((rand_helper_st *)dat)->prng); | |
22 | } | |
23 | 20 | |
24 | 21 | int rand_prime(void *N, long len, prng_state *prng, int wprng) |
25 | 22 | { |
26 | 23 | int err, res, type; |
27 | 24 | unsigned char *buf; |
28 | rand_helper_st rng; | |
29 | 25 | |
30 | 26 | LTC_ARGCHK(N != NULL); |
31 | 27 | |
38 | 34 | } |
39 | 35 | |
40 | 36 | /* allow sizes between 2 and 512 bytes for a prime size */ |
41 | if (len < 2 || len > 512) { | |
37 | if (len < 2 || len > 512) { | |
42 | 38 | return CRYPT_INVALID_PRIME_SIZE; |
43 | 39 | } |
44 | ||
40 | ||
45 | 41 | /* valid PRNG? Better be! */ |
46 | 42 | if ((err = prng_is_valid(wprng)) != CRYPT_OK) { |
47 | return err; | |
43 | return err; | |
48 | 44 | } |
49 | ||
50 | /* setup rng struct - used later for callback */ | |
51 | rng.prng = prng; | |
52 | rng.wprng = wprng; | |
53 | 45 | |
54 | 46 | /* allocate buffer to work with */ |
55 | 47 | buf = XCALLOC(1, len); |
67 | 59 | /* munge bits */ |
68 | 60 | buf[0] |= 0x80 | 0x40; |
69 | 61 | buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); |
70 | ||
62 | ||
71 | 63 | /* load value */ |
72 | 64 | if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { |
73 | 65 | XFREE(buf); |
75 | 67 | } |
76 | 68 | |
77 | 69 | /* test */ |
78 | if ((err = mp_prime_is_prime_ex(N, 0, &res, rand_helper, &rng)) != CRYPT_OK) { | |
70 | if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) { | |
79 | 71 | XFREE(buf); |
80 | 72 | return err; |
81 | 73 | } |
88 | 80 | XFREE(buf); |
89 | 81 | return CRYPT_OK; |
90 | 82 | } |
91 | ||
83 | ||
84 | #endif /* LTC_NO_MATH */ | |
92 | 85 | |
93 | 86 | |
94 | 87 | /* $Source$ */ |
24 | 24 | }; |
25 | 25 | |
26 | 26 | /** |
27 | Convert a tfm error to a LTC error (Possibly the most powerful function ever! Oh wait... no) | |
27 | Convert a tfm error to a LTC error (Possibly the most powerful function ever! Oh wait... no) | |
28 | 28 | @param err The error to convert |
29 | 29 | @return The equivalent LTC error code or CRYPT_ERROR if none found |
30 | 30 | */ |
33 | 33 | int x; |
34 | 34 | |
35 | 35 | for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) { |
36 | if (err == tfm_to_ltc_codes[x].tfm_code) { | |
36 | if (err == tfm_to_ltc_codes[x].tfm_code) { | |
37 | 37 | return tfm_to_ltc_codes[x].ltc_code; |
38 | 38 | } |
39 | 39 | } |
113 | 113 | A = a; |
114 | 114 | return A->used; |
115 | 115 | } |
116 | ||
116 | ||
117 | 117 | static int compare(void *a, void *b) |
118 | 118 | { |
119 | 119 | int ret; |
212 | 212 | fp_add(a, b, c); |
213 | 213 | return CRYPT_OK; |
214 | 214 | } |
215 | ||
215 | ||
216 | 216 | static int addi(void *a, unsigned long b, void *c) |
217 | 217 | { |
218 | 218 | LTC_ARGCHK(a != NULL); |
245 | 245 | LTC_ARGCHK(a != NULL); |
246 | 246 | LTC_ARGCHK(b != NULL); |
247 | 247 | LTC_ARGCHK(c != NULL); |
248 | fp_mul(a, b, c); | |
248 | fp_mul(a, b, c); | |
249 | 249 | return CRYPT_OK; |
250 | 250 | } |
251 | 251 | |
296 | 296 | } |
297 | 297 | *c = tmp; |
298 | 298 | return CRYPT_OK; |
299 | } | |
299 | } | |
300 | 300 | |
301 | 301 | /* gcd */ |
302 | 302 | static int gcd(void *a, void *b, void *c) |
410 | 410 | LTC_ARGCHK(c != NULL); |
411 | 411 | LTC_ARGCHK(d != NULL); |
412 | 412 | return tfm_to_ltc_error(fp_exptmod(a,b,c,d)); |
413 | } | |
414 | ||
415 | static int isprime(void *a, int *b) | |
416 | { | |
417 | LTC_ARGCHK(a != NULL); | |
418 | LTC_ARGCHK(b != NULL); | |
419 | *b = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO; | |
413 | } | |
414 | ||
415 | static int isprime(void *a, int b, int *c) | |
416 | { | |
417 | LTC_ARGCHK(a != NULL); | |
418 | LTC_ARGCHK(c != NULL); | |
419 | (void)b; | |
420 | *c = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO; | |
420 | 421 | return CRYPT_OK; |
421 | 422 | } |
422 | 423 | |
454 | 455 | if (fp_cmp(R->z, modulus) != FP_LT) { |
455 | 456 | fp_sub(R->z, modulus, R->z); |
456 | 457 | } |
457 | ||
458 | ||
458 | 459 | /* &t2 = X - T1 */ |
459 | 460 | fp_sub(R->x, &t1, &t2); |
460 | 461 | if (fp_cmp_d(&t2, 0) == FP_LT) { |
513 | 514 | fp_add(R->x, modulus, R->x); |
514 | 515 | } |
515 | 516 | |
516 | /* Y = Y - X */ | |
517 | /* Y = Y - X */ | |
517 | 518 | fp_sub(R->y, R->x, R->y); |
518 | 519 | if (fp_cmp_d(R->y, 0) == FP_LT) { |
519 | 520 | fp_add(R->y, modulus, R->y); |
526 | 527 | if (fp_cmp_d(R->y, 0) == FP_LT) { |
527 | 528 | fp_add(R->y, modulus, R->y); |
528 | 529 | } |
529 | ||
530 | ||
530 | 531 | return CRYPT_OK; |
531 | 532 | } |
532 | 533 | |
542 | 543 | static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp) |
543 | 544 | { |
544 | 545 | fp_int t1, t2, x, y, z; |
545 | fp_digit mp; | |
546 | ||
546 | fp_digit mp; | |
547 | ||
547 | 548 | LTC_ARGCHK(P != NULL); |
548 | 549 | LTC_ARGCHK(Q != NULL); |
549 | 550 | LTC_ARGCHK(R != NULL); |
560 | 561 | |
561 | 562 | /* should we dbl instead? */ |
562 | 563 | fp_sub(modulus, Q->y, &t1); |
563 | if ( (fp_cmp(P->x, Q->x) == FP_EQ) && | |
564 | if ( (fp_cmp(P->x, Q->x) == FP_EQ) && | |
564 | 565 | (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) && |
565 | 566 | (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { |
566 | 567 | return tfm_ecc_projective_dbl_point(P, R, modulus, Mp); |
653 | 654 | /* T1 = T1 * X */ |
654 | 655 | fp_mul(&t1, &x, &t1); |
655 | 656 | fp_montgomery_reduce(&t1, modulus, mp); |
656 | ||
657 | ||
657 | 658 | /* X = Y*Y */ |
658 | 659 | fp_sqr(&y, &x); |
659 | 660 | fp_montgomery_reduce(&x, modulus, mp); |
667 | 668 | fp_sub(&t2, &x, &t2); |
668 | 669 | if (fp_cmp_d(&t2, 0) == FP_LT) { |
669 | 670 | fp_add(&t2, modulus, &t2); |
670 | } | |
671 | } | |
671 | 672 | /* T2 = T2 - X */ |
672 | 673 | fp_sub(&t2, &x, &t2); |
673 | 674 | if (fp_cmp_d(&t2, 0) == FP_LT) { |
690 | 691 | fp_copy(&x, R->x); |
691 | 692 | fp_copy(&y, R->y); |
692 | 693 | fp_copy(&z, R->z); |
693 | ||
694 | ||
694 | 695 | return CRYPT_OK; |
695 | 696 | } |
696 | 697 | |
785 | 786 | #endif |
786 | 787 | &addmod, |
787 | 788 | &submod, |
788 | ||
789 | ||
789 | 790 | NULL, |
790 | 791 | |
791 | 792 | }; |
16 | 16 | */ |
17 | 17 | |
18 | 18 | |
19 | #ifdef LTC_BASE64 | |
19 | #if defined(LTC_BASE64) || defined (LTC_BASE64_URL) | |
20 | 20 | |
21 | #if defined(LTC_BASE64) | |
21 | 22 | static const unsigned char map_base64[256] = { |
22 | 23 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
23 | 24 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
41 | 42 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
42 | 43 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
43 | 44 | 255, 255, 255, 255 }; |
45 | #endif /* LTC_BASE64 */ | |
44 | 46 | |
47 | #if defined(LTC_BASE64_URL) | |
45 | 48 | static const unsigned char map_base64url[256] = { |
46 | 49 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
47 | 50 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
65 | 68 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
66 | 69 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
67 | 70 | 255, 255, 255, 255 }; |
71 | #endif /* LTC_BASE64_URL */ | |
68 | 72 | |
69 | int base64_decode_internal(const unsigned char *in, unsigned long inlen, | |
73 | static int _base64_decode_internal(const unsigned char *in, unsigned long inlen, | |
70 | 74 | unsigned char *out, unsigned long *outlen, |
71 | 75 | const unsigned char *map) |
72 | 76 | { |
83 | 87 | c = map[in[x]&0xFF]; |
84 | 88 | if (c == 255) continue; |
85 | 89 | /* the final = symbols are read and used to trim the remaining bytes */ |
86 | if (c == 254) { | |
87 | c = 0; | |
90 | if (c == 254) { | |
91 | c = 0; | |
88 | 92 | /* prevent g < 0 which would potentially allow an overflow later */ |
89 | 93 | if (--g < 0) { |
90 | 94 | return CRYPT_INVALID_PACKET; |
97 | 101 | t = (t<<6)|c; |
98 | 102 | |
99 | 103 | if (++y == 4) { |
100 | if (z + g > *outlen) { | |
101 | return CRYPT_BUFFER_OVERFLOW; | |
104 | if (z + g > *outlen) { | |
105 | return CRYPT_BUFFER_OVERFLOW; | |
102 | 106 | } |
103 | 107 | out[z++] = (unsigned char)((t>>16)&255); |
104 | 108 | if (g > 1) out[z++] = (unsigned char)((t>>8)&255); |
113 | 117 | return CRYPT_OK; |
114 | 118 | } |
115 | 119 | |
120 | #if defined(LTC_BASE64) | |
116 | 121 | /** |
117 | 122 | base64 decode a block of memory |
118 | 123 | @param in The base64 data to decode |
121 | 126 | @param outlen [in/out] The max size and resulting size of the decoded data |
122 | 127 | @return CRYPT_OK if successful |
123 | 128 | */ |
124 | int base64_decode(const unsigned char *in, unsigned long inlen, | |
129 | int base64_decode(const unsigned char *in, unsigned long inlen, | |
125 | 130 | unsigned char *out, unsigned long *outlen) |
126 | 131 | { |
127 | return base64_decode_internal(in, inlen, out, outlen, map_base64); | |
132 | return _base64_decode_internal(in, inlen, out, outlen, map_base64); | |
128 | 133 | } |
134 | #endif /* LTC_BASE64 */ | |
129 | 135 | |
136 | #if defined(LTC_BASE64_URL) | |
130 | 137 | /** |
131 | 138 | base64 (URL Safe, RFC 4648 section 5) decode a block of memory |
132 | 139 | @param in The base64 data to decode |
135 | 142 | @param outlen [in/out] The max size and resulting size of the decoded data |
136 | 143 | @return CRYPT_OK if successful |
137 | 144 | */ |
138 | int base64url_decode(const unsigned char *in, unsigned long inlen, | |
145 | int base64url_decode(const unsigned char *in, unsigned long inlen, | |
139 | 146 | unsigned char *out, unsigned long *outlen) |
140 | 147 | { |
141 | return base64_decode_internal(in, inlen, out, outlen, map_base64url); | |
148 | return _base64_decode_internal(in, inlen, out, outlen, map_base64url); | |
142 | 149 | } |
150 | #endif /* LTC_BASE64_URL */ | |
143 | 151 | |
144 | 152 | #endif |
145 | 153 |
16 | 16 | */ |
17 | 17 | |
18 | 18 | |
19 | #ifdef LTC_BASE64 | |
19 | #if defined(LTC_BASE64) || defined (LTC_BASE64_URL) | |
20 | 20 | |
21 | #if defined(LTC_BASE64) | |
21 | 22 | static const char *codes_base64 = |
22 | 23 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
24 | #endif /* LTC_BASE64 */ | |
23 | 25 | |
26 | #if defined(LTC_BASE64_URL) | |
24 | 27 | static const char *codes_base64url = |
25 | 28 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; |
29 | #endif /* LTC_BASE64_URL */ | |
26 | 30 | |
27 | int base64_encode_internal(const unsigned char *in, unsigned long inlen, | |
31 | static int _base64_encode_internal(const unsigned char *in, unsigned long inlen, | |
28 | 32 | unsigned char *out, unsigned long *outlen, |
29 | 33 | const char *codes, int pad) |
30 | 34 | { |
74 | 78 | return CRYPT_OK; |
75 | 79 | } |
76 | 80 | |
81 | #if defined(LTC_BASE64) | |
77 | 82 | /** |
78 | 83 | base64 Encode a buffer (NUL terminated) |
79 | 84 | @param in The input buffer to encode |
82 | 87 | @param outlen [in/out] The max size and resulting size |
83 | 88 | @return CRYPT_OK if successful |
84 | 89 | */ |
85 | int base64_encode(const unsigned char *in, unsigned long inlen, | |
90 | int base64_encode(const unsigned char *in, unsigned long inlen, | |
86 | 91 | unsigned char *out, unsigned long *outlen) |
87 | 92 | { |
88 | return base64_encode_internal(in, inlen, out, outlen, codes_base64, 1); | |
93 | return _base64_encode_internal(in, inlen, out, outlen, codes_base64, 1); | |
89 | 94 | } |
95 | #endif /* LTC_BASE64 */ | |
90 | 96 | |
97 | ||
98 | #if defined(LTC_BASE64_URL) | |
91 | 99 | /** |
92 | 100 | base64 (URL Safe, RFC 4648 section 5) Encode a buffer (NUL terminated) |
93 | 101 | @param in The input buffer to encode |
96 | 104 | @param outlen [in/out] The max size and resulting size |
97 | 105 | @return CRYPT_OK if successful |
98 | 106 | */ |
99 | int base64url_encode(const unsigned char *in, unsigned long inlen, | |
107 | int base64url_encode(const unsigned char *in, unsigned long inlen, | |
100 | 108 | unsigned char *out, unsigned long *outlen) |
101 | 109 | { |
102 | return base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0); | |
110 | return _base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0); | |
103 | 111 | } |
112 | #endif /* LTC_BASE64_URL */ | |
104 | 113 | |
105 | 114 | #endif |
106 | 115 |
12 | 12 | /** |
13 | 13 | @file crypt.c |
14 | 14 | Build strings, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | const char *crypt_build_settings = |
18 | 18 | "LibTomCrypt " SCRYPT " (Tom St Denis, tomstdenis@gmail.com)\n" |
19 | 19 | "LibTomCrypt is public domain software.\n" |
20 | 20 | "Built on " __DATE__ " at " __TIME__ "\n\n\n" |
21 | "Endianess: " | |
21 | "Endianness: " | |
22 | 22 | #if defined(ENDIAN_NEUTRAL) |
23 | 23 | "neutral\n" |
24 | 24 | #elif defined(ENDIAN_LITTLE) |
47 | 47 | " Blowfish\n" |
48 | 48 | #endif |
49 | 49 | #if defined(LTC_RC2) |
50 | " LTC_RC2\n" | |
50 | " RC2\n" | |
51 | 51 | #endif |
52 | 52 | #if defined(LTC_RC5) |
53 | " LTC_RC5\n" | |
53 | " RC5\n" | |
54 | 54 | #endif |
55 | 55 | #if defined(LTC_RC6) |
56 | " LTC_RC6\n" | |
56 | " RC6\n" | |
57 | 57 | #endif |
58 | 58 | #if defined(LTC_SAFERP) |
59 | 59 | " Safer+\n" |
65 | 65 | " Rijndael\n" |
66 | 66 | #endif |
67 | 67 | #if defined(LTC_XTEA) |
68 | " LTC_XTEA\n" | |
68 | " XTEA\n" | |
69 | 69 | #endif |
70 | 70 | #if defined(LTC_TWOFISH) |
71 | 71 | " Twofish " |
88 | 88 | #endif |
89 | 89 | #endif |
90 | 90 | #if defined(LTC_DES) |
91 | " LTC_DES\n" | |
91 | " DES\n" | |
92 | 92 | #endif |
93 | 93 | #if defined(LTC_CAST5) |
94 | " LTC_CAST5\n" | |
94 | " CAST5\n" | |
95 | 95 | #endif |
96 | 96 | #if defined(LTC_NOEKEON) |
97 | 97 | " Noekeon\n" |
110 | 110 | #endif |
111 | 111 | "\n" |
112 | 112 | #if defined(LTC_KSEED) |
113 | " LTC_KSEED\n" | |
113 | " KSEED\n" | |
114 | 114 | #endif |
115 | 115 | #if defined(LTC_KASUMI) |
116 | 116 | " KASUMI\n" |
124 | 124 | |
125 | 125 | "\nHashes built-in:\n" |
126 | 126 | #if defined(LTC_SHA512) |
127 | " LTC_SHA-512\n" | |
127 | " SHA-512\n" | |
128 | 128 | #endif |
129 | 129 | #if defined(LTC_SHA384) |
130 | " LTC_SHA-384\n" | |
130 | " SHA-384\n" | |
131 | 131 | #endif |
132 | 132 | #if defined(LTC_SHA256) |
133 | " LTC_SHA-256\n" | |
133 | " SHA-256\n" | |
134 | 134 | #endif |
135 | 135 | #if defined(LTC_SHA224) |
136 | " LTC_SHA-224\n" | |
136 | " SHA-224\n" | |
137 | 137 | #endif |
138 | 138 | #if defined(LTC_TIGER) |
139 | " LTC_TIGER\n" | |
139 | " TIGER\n" | |
140 | 140 | #endif |
141 | 141 | #if defined(LTC_SHA1) |
142 | " LTC_SHA1\n" | |
142 | " SHA1\n" | |
143 | 143 | #endif |
144 | 144 | #if defined(LTC_MD5) |
145 | " LTC_MD5\n" | |
145 | " MD5\n" | |
146 | 146 | #endif |
147 | 147 | #if defined(LTC_MD4) |
148 | " LTC_MD4\n" | |
148 | " MD4\n" | |
149 | 149 | #endif |
150 | 150 | #if defined(LTC_MD2) |
151 | " LTC_MD2\n" | |
151 | " MD2\n" | |
152 | 152 | #endif |
153 | 153 | #if defined(LTC_RIPEMD128) |
154 | " LTC_RIPEMD128\n" | |
154 | " RIPEMD128\n" | |
155 | 155 | #endif |
156 | 156 | #if defined(LTC_RIPEMD160) |
157 | " LTC_RIPEMD160\n" | |
157 | " RIPEMD160\n" | |
158 | 158 | #endif |
159 | 159 | #if defined(LTC_RIPEMD256) |
160 | " LTC_RIPEMD256\n" | |
160 | " RIPEMD256\n" | |
161 | 161 | #endif |
162 | 162 | #if defined(LTC_RIPEMD320) |
163 | " LTC_RIPEMD320\n" | |
163 | " RIPEMD320\n" | |
164 | 164 | #endif |
165 | 165 | #if defined(LTC_WHIRLPOOL) |
166 | " LTC_WHIRLPOOL\n" | |
166 | " WHIRLPOOL\n" | |
167 | 167 | #endif |
168 | 168 | #if defined(LTC_CHC_HASH) |
169 | " LTC_CHC_HASH \n" | |
169 | " CHC_HASH\n" | |
170 | 170 | #endif |
171 | 171 | |
172 | 172 | "\nBlock Chaining Modes:\n" |
189 | 189 | " (CTR_OLD) " |
190 | 190 | #endif |
191 | 191 | "\n" |
192 | #if defined(LRW_MODE) | |
193 | " LRW_MODE" | |
192 | #if defined(LTC_LRW_MODE) | |
193 | " LRW" | |
194 | 194 | #if defined(LRW_TABLES) |
195 | " (LRW_TABLES) " | |
195 | " (tables) " | |
196 | 196 | #endif |
197 | 197 | "\n" |
198 | 198 | #endif |
199 | 199 | #if defined(LTC_F8_MODE) |
200 | " F8 MODE\n" | |
201 | #endif | |
200 | " F8\n" | |
201 | #endif | |
202 | 202 | #if defined(LTC_XTS_MODE) |
203 | " LTC_XTS_MODE\n" | |
203 | " XTS\n" | |
204 | 204 | #endif |
205 | 205 | |
206 | 206 | "\nMACs:\n" |
207 | 207 | #if defined(LTC_HMAC) |
208 | " LTC_HMAC\n" | |
208 | " HMAC\n" | |
209 | 209 | #endif |
210 | 210 | #if defined(LTC_OMAC) |
211 | " LTC_OMAC\n" | |
211 | " OMAC\n" | |
212 | 212 | #endif |
213 | 213 | #if defined(LTC_PMAC) |
214 | 214 | " PMAC\n" |
215 | 215 | #endif |
216 | 216 | #if defined(LTC_PELICAN) |
217 | " LTC_PELICAN\n" | |
217 | " PELICAN\n" | |
218 | 218 | #endif |
219 | 219 | #if defined(LTC_XCBC) |
220 | " XCBC-MAC\n" | |
220 | " XCBC\n" | |
221 | 221 | #endif |
222 | 222 | #if defined(LTC_F9_MODE) |
223 | " F9-MAC\n" | |
223 | " F9\n" | |
224 | 224 | #endif |
225 | 225 | |
226 | 226 | "\nENC + AUTH modes:\n" |
227 | 227 | #if defined(LTC_EAX_MODE) |
228 | " LTC_EAX_MODE\n" | |
228 | " EAX\n" | |
229 | 229 | #endif |
230 | 230 | #if defined(LTC_OCB_MODE) |
231 | " LTC_OCB_MODE\n" | |
231 | " OCB\n" | |
232 | 232 | #endif |
233 | 233 | #if defined(LTC_OCB3_MODE) |
234 | " LTC_OCB3_MODE\n" | |
234 | " OCB3\n" | |
235 | 235 | #endif |
236 | 236 | #if defined(LTC_CCM_MODE) |
237 | " LTC_CCM_MODE\n" | |
237 | " CCM\n" | |
238 | 238 | #endif |
239 | 239 | #if defined(LTC_GCM_MODE) |
240 | " LTC_GCM_MODE " | |
241 | #endif | |
240 | " GCM" | |
242 | 241 | #if defined(LTC_GCM_TABLES) |
243 | " (LTC_GCM_TABLES) " | |
242 | " (tables) " | |
243 | #endif | |
244 | #if defined(LTC_GCM_TABLES_SSE2) | |
245 | " (SSE2) " | |
244 | 246 | #endif |
245 | 247 | "\n" |
248 | #endif | |
246 | 249 | |
247 | 250 | "\nPRNG:\n" |
248 | 251 | #if defined(LTC_YARROW) |
249 | 252 | " Yarrow\n" |
250 | 253 | #endif |
251 | 254 | #if defined(LTC_SPRNG) |
252 | " LTC_SPRNG\n" | |
255 | " SPRNG\n" | |
253 | 256 | #endif |
254 | 257 | #if defined(LTC_RC4) |
255 | " LTC_RC4\n" | |
258 | " RC4\n" | |
256 | 259 | #endif |
257 | 260 | #if defined(LTC_FORTUNA) |
258 | 261 | " Fortuna\n" |
259 | 262 | #endif |
260 | 263 | #if defined(LTC_SOBER128) |
261 | " LTC_SOBER128\n" | |
264 | " SOBER128\n" | |
262 | 265 | #endif |
263 | 266 | |
264 | 267 | "\nPK Algs:\n" |
265 | 268 | #if defined(LTC_MRSA) |
266 | " RSA \n" | |
269 | " RSA" | |
270 | #if defined(LTC_RSA_BLINDING) | |
271 | " (with blinding)" | |
272 | #endif | |
273 | "\n" | |
274 | #endif | |
275 | #if defined(LTC_MDH) | |
276 | " DH\n" | |
267 | 277 | #endif |
268 | 278 | #if defined(LTC_MECC) |
269 | 279 | " ECC\n" |
273 | 283 | #endif |
274 | 284 | #if defined(MKAT) |
275 | 285 | " Katja\n" |
276 | #endif | |
286 | #endif | |
277 | 287 | |
278 | 288 | "\nCompiler:\n" |
279 | 289 | #if defined(WIN32) |
300 | 310 | " x86-64 detected.\n" |
301 | 311 | #endif |
302 | 312 | #if defined(LTC_PPC32) |
303 | " LTC_PPC32 defined \n" | |
304 | #endif | |
313 | " PPC32 defined \n" | |
314 | #endif | |
305 | 315 | |
306 | 316 | "\nVarious others: " |
307 | 317 | #if defined(LTC_BASE64) |
308 | " LTC_BASE64 " | |
318 | " BASE64 " | |
319 | #endif | |
320 | #if defined(LTC_BASE64_URL) | |
321 | " BASE64-URL-SAFE " | |
322 | #endif | |
323 | #if defined(LTC_DER) | |
324 | " DER " | |
325 | #endif | |
326 | #if defined(LTC_PKCS_1) | |
327 | " PKCS#1 " | |
328 | #endif | |
329 | #if defined(LTC_PKCS_5) | |
330 | " PKCS#5 " | |
331 | #endif | |
332 | #if defined(LTC_HKDF) | |
333 | " HKDF " | |
309 | 334 | #endif |
310 | 335 | #if defined(MPI) |
311 | 336 | " MPI " |
312 | 337 | #endif |
313 | #if defined(TRY_UNRANDOM_FIRST) | |
314 | " TRY_UNRANDOM_FIRST " | |
338 | #if defined(TRY_URANDOM_FIRST) | |
339 | " TRY_URANDOM_FIRST " | |
315 | 340 | #endif |
316 | 341 | #if defined(LTC_TEST) |
317 | 342 | " LTC_TEST " |
318 | 343 | #endif |
319 | #if defined(LTC_PKCS_1) | |
320 | " LTC_PKCS#1 " | |
321 | #endif | |
322 | #if defined(LTC_PKCS_5) | |
323 | " LTC_PKCS#5 " | |
324 | #endif | |
325 | 344 | #if defined(LTC_SMALL_CODE) |
326 | 345 | " LTC_SMALL_CODE " |
327 | 346 | #endif |
328 | 347 | #if defined(LTC_NO_FILE) |
329 | 348 | " LTC_NO_FILE " |
330 | 349 | #endif |
331 | #if defined(LTC_DER) | |
332 | " LTC_DER " | |
333 | #endif | |
334 | 350 | #if defined(LTC_FAST) |
335 | 351 | " LTC_FAST " |
336 | 352 | #endif |
352 | 368 | #if defined(LTC_PTHREAD) |
353 | 369 | " LTC_PTHREAD " |
354 | 370 | #endif |
355 | #if defined(LTM_LTC_DESC) | |
371 | #if defined(LTM_DESC) | |
356 | 372 | " LTM_DESC " |
357 | 373 | #endif |
358 | #if defined(TFM_LTC_DESC) | |
374 | #if defined(TFM_DESC) | |
359 | 375 | " TFM_DESC " |
360 | 376 | #endif |
361 | 377 | #if defined(LTC_MECC_ACCEL) |
362 | 378 | " LTC_MECC_ACCEL " |
363 | 379 | #endif |
364 | #if defined(GMP_LTC_DESC) | |
380 | #if defined(GMP_DESC) | |
365 | 381 | " GMP_DESC " |
366 | 382 | #endif |
367 | 383 | #if defined(LTC_EASY) |
368 | " (easy) " | |
369 | #endif | |
384 | " LTC_EASY " | |
385 | #endif | |
370 | 386 | #if defined(LTC_MECC_FP) |
371 | 387 | " LTC_MECC_FP " |
372 | 388 | #endif |
8 | 8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | #include <signal.h> | |
12 | 11 | |
13 | 12 | /** |
14 | 13 | @file crypt_argchk.c |
16 | 15 | */ |
17 | 16 | |
18 | 17 | #if (ARGTYPE == 0) |
18 | #include <signal.h> | |
19 | 19 | void crypt_argchk(char *v, char *s, int d) |
20 | 20 | { |
21 | 21 | fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n", |
2 | 2 | #include <stdlib.h> |
3 | 3 | |
4 | 4 | #include <tomcrypt.h> |
5 | ||
6 | #ifdef LTC_HKDF | |
5 | 7 | |
6 | 8 | #ifndef MIN |
7 | 9 | #define MIN(a,b) ((a)<(b))?(a):(b) |
135 | 137 | XFREE(extracted); |
136 | 138 | return err; |
137 | 139 | } |
140 | #endif /* LTC_HKDF */ | |
138 | 141 | |
139 | 142 | |
140 | 143 | /* vim: set ts=2 sw=2 et ai si: */ |
9 | 9 | */ |
10 | 10 | #include <tomcrypt.h> |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_5_1.c |
14 | LTC_PKCS #5, Algorithm #1, Tom St Denis | |
14 | PKCS #5, Algorithm #1, Tom St Denis | |
15 | 15 | */ |
16 | 16 | #ifdef LTC_PKCS_5 |
17 | 17 | /** |
18 | Execute LTC_PKCS #5 v1 | |
18 | Execute PKCS #5 v1 | |
19 | 19 | @param password The password (or key) |
20 | 20 | @param password_len The length of the password (octet) |
21 | 21 | @param salt The salt (or nonce) which is 8 octets long |
22 | @param iteration_count The LTC_PKCS #5 v1 iteration count | |
22 | @param iteration_count The PKCS #5 v1 iteration count | |
23 | 23 | @param hash_idx The index of the hash desired |
24 | 24 | @param out [out] The destination for this algorithm |
25 | 25 | @param outlen [in/out] The max size and resulting size of the algorithm output |
26 | 26 | @return CRYPT_OK if successful |
27 | 27 | */ |
28 | int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, | |
29 | const unsigned char *salt, | |
28 | int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, | |
29 | const unsigned char *salt, | |
30 | 30 | int iteration_count, int hash_idx, |
31 | 31 | unsigned char *out, unsigned long *outlen) |
32 | 32 | { |
52 | 52 | if (md != NULL) { |
53 | 53 | XFREE(md); |
54 | 54 | } |
55 | if (buf != NULL) { | |
55 | if (buf != NULL) { | |
56 | 56 | XFREE(buf); |
57 | 57 | } |
58 | 58 | return CRYPT_MEM; |
59 | } | |
59 | } | |
60 | 60 | |
61 | 61 | /* hash initial password + salt */ |
62 | 62 | if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { |
87 | 87 | *outlen = x; |
88 | 88 | err = CRYPT_OK; |
89 | 89 | LBL_ERR: |
90 | #ifdef LTC_CLEAN_STACK | |
90 | #ifdef LTC_CLEAN_STACK | |
91 | 91 | zeromem(buf, MAXBLOCKSIZE); |
92 | 92 | zeromem(md, sizeof(hash_state)); |
93 | 93 | #endif |
9 | 9 | */ |
10 | 10 | #include <tomcrypt.h> |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_5_2.c |
14 | LTC_PKCS #5, Algorithm #2, Tom St Denis | |
14 | PKCS #5, Algorithm #2, Tom St Denis | |
15 | 15 | */ |
16 | 16 | #ifdef LTC_PKCS_5 |
17 | 17 | |
18 | 18 | /** |
19 | Execute LTC_PKCS #5 v2 | |
19 | Execute PKCS #5 v2 | |
20 | 20 | @param password The input password (or key) |
21 | 21 | @param password_len The length of the password (octets) |
22 | 22 | @param salt The salt (or nonce) |
23 | 23 | @param salt_len The length of the salt (octets) |
24 | @param iteration_count # of iterations desired for LTC_PKCS #5 v2 [read specs for more] | |
24 | @param iteration_count # of iterations desired for PKCS #5 v2 [read specs for more] | |
25 | 25 | @param hash_idx The index of the hash desired |
26 | 26 | @param out [out] The destination for this algorithm |
27 | 27 | @param outlen [in/out] The max size and resulting size of the algorithm output |
28 | 28 | @return CRYPT_OK if successful |
29 | 29 | */ |
30 | int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, | |
30 | int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, | |
31 | 31 | const unsigned char *salt, unsigned long salt_len, |
32 | 32 | int iteration_count, int hash_idx, |
33 | 33 | unsigned char *out, unsigned long *outlen) |
68 | 68 | while (left != 0) { |
69 | 69 | /* process block number blkno */ |
70 | 70 | zeromem(buf[0], MAXBLOCKSIZE*2); |
71 | ||
71 | ||
72 | 72 | /* store current block number and increment for next pass */ |
73 | 73 | STORE32H(blkno, buf[1]); |
74 | 74 | ++blkno; |
75 | 75 | |
76 | 76 | /* get PRF(P, S||int(blkno)) */ |
77 | if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { | |
77 | if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { | |
78 | 78 | goto LBL_ERR; |
79 | 79 | } |
80 | 80 | if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) { |
33 | 33 | LTC_FAST_TYPE tmpy; |
34 | 34 | #else |
35 | 35 | unsigned char tmpy; |
36 | #endif | |
36 | #endif | |
37 | 37 | |
38 | 38 | LTC_ARGCHK(pt != NULL); |
39 | 39 | LTC_ARGCHK(ct != NULL); |
42 | 42 | if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { |
43 | 43 | return err; |
44 | 44 | } |
45 | ||
45 | ||
46 | 46 | /* is blocklen valid? */ |
47 | 47 | if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { |
48 | 48 | return CRYPT_INVALID_ARG; |
49 | } | |
49 | } | |
50 | 50 | |
51 | 51 | if (len % cbc->blocklen) { |
52 | 52 | return CRYPT_INVALID_ARG; |
53 | 53 | } |
54 | 54 | #ifdef LTC_FAST |
55 | if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { | |
55 | if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { | |
56 | 56 | return CRYPT_INVALID_ARG; |
57 | 57 | } |
58 | 58 | #endif |
59 | ||
59 | ||
60 | 60 | if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { |
61 | 61 | return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); |
62 | 62 | } else { |
73 | 73 | *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); |
74 | 74 | *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy; |
75 | 75 | } |
76 | #else | |
76 | #else | |
77 | 77 | for (x = 0; x < cbc->blocklen; x++) { |
78 | 78 | tmpy = tmp[x] ^ cbc->IV[x]; |
79 | 79 | cbc->IV[x] = ct[x]; |
80 | 80 | pt[x] = tmpy; |
81 | 81 | } |
82 | 82 | #endif |
83 | ||
83 | ||
84 | 84 | ct += cbc->blocklen; |
85 | 85 | pt += cbc->blocklen; |
86 | 86 | len -= cbc->blocklen; |
36 | 36 | if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { |
37 | 37 | return err; |
38 | 38 | } |
39 | ||
39 | ||
40 | 40 | /* is blocklen valid? */ |
41 | 41 | if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { |
42 | 42 | return CRYPT_INVALID_ARG; |
43 | } | |
43 | } | |
44 | 44 | |
45 | 45 | if (len % cbc->blocklen) { |
46 | 46 | return CRYPT_INVALID_ARG; |
47 | 47 | } |
48 | 48 | #ifdef LTC_FAST |
49 | if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { | |
49 | if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { | |
50 | 50 | return CRYPT_INVALID_ARG; |
51 | 51 | } |
52 | 52 | #endif |
60 | 60 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { |
61 | 61 | *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x)); |
62 | 62 | } |
63 | #else | |
63 | #else | |
64 | 64 | for (x = 0; x < cbc->blocklen; x++) { |
65 | 65 | cbc->IV[x] ^= pt[x]; |
66 | 66 | } |
76 | 76 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { |
77 | 77 | *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); |
78 | 78 | } |
79 | #else | |
79 | #else | |
80 | 80 | for (x = 0; x < cbc->blocklen; x++) { |
81 | 81 | cbc->IV[x] = ct[x]; |
82 | 82 | } |
83 | 83 | #endif |
84 | ||
84 | ||
85 | 85 | ct += cbc->blocklen; |
86 | 86 | pt += cbc->blocklen; |
87 | 87 | len -= cbc->blocklen; |
36 | 36 | if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { |
37 | 37 | return err; |
38 | 38 | } |
39 | ||
39 | ||
40 | 40 | /* is blocklen/padlen valid? */ |
41 | 41 | if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || |
42 | 42 | ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { |
48 | 48 | return CRYPT_INVALID_ARG; |
49 | 49 | } |
50 | 50 | #endif |
51 | ||
51 | ||
52 | 52 | /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ |
53 | 53 | if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { |
54 | 54 | if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { |
97 | 97 | ctr->padlen = ctr->blocklen; |
98 | 98 | continue; |
99 | 99 | } |
100 | #endif | |
100 | #endif | |
101 | 101 | *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; |
102 | 102 | --len; |
103 | 103 | } |
100 | 100 | |
101 | 101 | #endif |
102 | 102 | |
103 | /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */ | |
104 | /* $Revision: 1.5 $ */ | |
105 | /* $Date: 2006/12/28 01:27:24 $ */ | |
103 | /* $Source$ */ | |
104 | /* $Revision$ */ | |
105 | /* $Date$ */ |
86 | 86 | |
87 | 87 | #endif |
88 | 88 | |
89 | /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */ | |
90 | /* $Revision: 1.5 $ */ | |
91 | /* $Date: 2006/12/28 01:27:24 $ */ | |
89 | /* $Source$ */ | |
90 | /* $Revision$ */ | |
91 | /* $Date$ */ |
17 | 17 | |
18 | 18 | #ifdef LTC_DER |
19 | 19 | /** |
20 | Gets length of DER encoding of num | |
21 | @param num The int to get the size of | |
20 | Gets length of DER encoding of num | |
21 | @param num The int to get the size of | |
22 | 22 | @param outlen [out] The length of the DER encoding for the given integer |
23 | 23 | @return CRYPT_OK if successful |
24 | 24 | */ |
70 | 70 | ++len; |
71 | 71 | |
72 | 72 | /* return length */ |
73 | *outlen = len; | |
73 | *outlen = len; | |
74 | 74 | return CRYPT_OK; |
75 | 75 | } |
76 | 76 |
26 | 26 | struct edge *A = (struct edge *)a, *B = (struct edge *)b; |
27 | 27 | int r; |
28 | 28 | unsigned long x; |
29 | ||
29 | ||
30 | 30 | /* compare min length */ |
31 | 31 | r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); |
32 | ||
32 | ||
33 | 33 | if (r == 0 && A->size != B->size) { |
34 | 34 | if (A->size > B->size) { |
35 | 35 | for (x = B->size; x < A->size; x++) { |
43 | 43 | return -1; |
44 | 44 | } |
45 | 45 | } |
46 | } | |
46 | } | |
47 | 47 | } |
48 | ||
49 | return r; | |
48 | ||
49 | return r; | |
50 | 50 | } |
51 | 51 | |
52 | 52 | /** |
53 | 53 | Encode a SETOF stucture |
54 | 54 | @param list The list of items to encode |
55 | 55 | @param inlen The number of items in the list |
56 | @param out [out] The destination | |
56 | @param out [out] The destination | |
57 | 57 | @param outlen [in/out] The size of the output |
58 | 58 | @return CRYPT_OK on success |
59 | */ | |
59 | */ | |
60 | 60 | int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, |
61 | 61 | unsigned char *out, unsigned long *outlen) |
62 | 62 | { |
63 | unsigned long x, y, z, hdrlen; | |
63 | unsigned long x, y, z; | |
64 | ptrdiff_t hdrlen; | |
64 | 65 | int err; |
65 | 66 | struct edge *edges; |
66 | 67 | unsigned char *ptr, *buf; |
67 | ||
68 | ||
68 | 69 | /* check that they're all the same type */ |
69 | 70 | for (x = 1; x < inlen; x++) { |
70 | 71 | if (list[x].type != list[x-1].type) { |
76 | 77 | buf = XCALLOC(1, *outlen); |
77 | 78 | if (buf == NULL) { |
78 | 79 | return CRYPT_MEM; |
79 | } | |
80 | ||
80 | } | |
81 | ||
81 | 82 | /* encode list */ |
82 | 83 | if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { |
83 | 84 | XFREE(buf); |
84 | 85 | return err; |
85 | 86 | } |
86 | ||
87 | ||
87 | 88 | /* allocate edges */ |
88 | 89 | edges = XCALLOC(inlen, sizeof(*edges)); |
89 | 90 | if (edges == NULL) { |
90 | 91 | XFREE(buf); |
91 | 92 | return CRYPT_MEM; |
92 | } | |
93 | ||
93 | } | |
94 | ||
94 | 95 | /* skip header */ |
95 | 96 | ptr = buf + 1; |
96 | 97 | |
99 | 100 | if (x >= 0x80) { |
100 | 101 | ptr += (x & 0x7F); |
101 | 102 | } |
102 | ||
103 | ||
103 | 104 | /* get the size of the static header */ |
104 | hdrlen = (unsigned long)(ptr - buf); | |
105 | ||
106 | ||
105 | hdrlen = ptr - buf; | |
106 | ||
107 | ||
107 | 108 | /* scan for edges */ |
108 | 109 | x = 0; |
109 | 110 | while (ptr < (buf + *outlen)) { |
110 | 111 | /* store start */ |
111 | 112 | edges[x].start = ptr; |
112 | ||
113 | ||
113 | 114 | /* skip type */ |
114 | 115 | z = 1; |
115 | ||
116 | ||
116 | 117 | /* parse length */ |
117 | 118 | y = ptr[z++]; |
118 | 119 | if (y < 128) { |
124 | 125 | edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); |
125 | 126 | } |
126 | 127 | } |
127 | ||
128 | ||
128 | 129 | /* skip content */ |
129 | 130 | edges[x].size += z; |
130 | 131 | ptr += edges[x].size; |
131 | 132 | ++x; |
132 | } | |
133 | ||
133 | } | |
134 | ||
134 | 135 | /* sort based on contents (using edges) */ |
135 | 136 | XQSORT(edges, inlen, sizeof(*edges), &qsort_helper); |
136 | ||
137 | ||
137 | 138 | /* copy static header */ |
138 | 139 | XMEMCPY(out, buf, hdrlen); |
139 | ||
140 | ||
140 | 141 | /* copy+sort using edges+indecies to output from buffer */ |
141 | 142 | for (y = hdrlen, x = 0; x < inlen; x++) { |
142 | 143 | XMEMCPY(out+y, edges[x].start, edges[x].size); |
143 | 144 | y += edges[x].size; |
144 | } | |
145 | ||
145 | } | |
146 | ||
146 | 147 | #ifdef LTC_CLEAN_STACK |
147 | 148 | zeromem(buf, *outlen); |
148 | #endif | |
149 | ||
149 | #endif | |
150 | ||
150 | 151 | /* free buffers */ |
151 | 152 | XFREE(edges); |
152 | 153 | XFREE(buf); |
153 | ||
154 | ||
154 | 155 | return CRYPT_OK; |
155 | 156 | } |
156 | 157 |
13 | 13 | @file dh.c |
14 | 14 | DH crypto, Tom St Denis |
15 | 15 | */ |
16 | ||
17 | #ifdef MDH | |
18 | ||
19 | /* size of a packet header in bytes */ | |
20 | #define PACKET_SIZE 4 | |
21 | ||
22 | /* Section tags */ | |
23 | #define PACKET_SECT_DH 1 | |
24 | ||
25 | /* Subsection Tags for the first three sections */ | |
26 | #define PACKET_SUB_KEY 0 | |
27 | #define PACKET_SUB_ENCRYPTED 1 | |
28 | #define PACKET_SUB_SIGNED 2 | |
29 | #define PACKET_SUB_ENC_KEY 3 | |
30 | ||
31 | #define OUTPUT_BIGNUM(num, out, y, z) \ | |
32 | { \ | |
33 | if ((y + 4) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ | |
34 | z = (unsigned long)mp_unsigned_bin_size(num); \ | |
35 | STORE32L(z, out+y); \ | |
36 | y += 4; \ | |
37 | if ((y + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ | |
38 | if ((err = mp_to_unsigned_bin(num, out+y)) != CRYPT_OK) { return err; } \ | |
39 | y += z; \ | |
40 | } | |
41 | ||
42 | #define INPUT_BIGNUM(num, in, x, y, inlen) \ | |
43 | { \ | |
44 | /* load value */ \ | |
45 | if ((y + 4) > inlen) { \ | |
46 | err = CRYPT_INVALID_PACKET; \ | |
47 | goto error; \ | |
48 | } \ | |
49 | LOAD32L(x, in+y); \ | |
50 | y += 4; \ | |
51 | \ | |
52 | /* sanity check... */ \ | |
53 | if ((x+y) > inlen) { \ | |
54 | err = CRYPT_INVALID_PACKET; \ | |
55 | goto error; \ | |
56 | } \ | |
57 | \ | |
58 | /* load it */ \ | |
59 | if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != CRYPT_OK) {\ | |
60 | goto error; \ | |
61 | } \ | |
62 | y += x; \ | |
63 | } | |
64 | ||
65 | static void packet_store_header(unsigned char *dst, int section, int subsection) | |
66 | { | |
67 | LTC_ARGCHK(dst != NULL); | |
68 | ||
69 | /* store version number */ | |
70 | dst[0] = (unsigned char)(CRYPT&255); | |
71 | dst[1] = (unsigned char)((CRYPT>>8)&255); | |
72 | ||
73 | /* store section and subsection */ | |
74 | dst[2] = (unsigned char)(section & 255); | |
75 | dst[3] = (unsigned char)(subsection & 255); | |
76 | ||
77 | } | |
78 | ||
79 | static int packet_valid_header(unsigned char *src, int section, int subsection) | |
80 | { | |
81 | unsigned long ver; | |
82 | ||
83 | LTC_ARGCHK(src != NULL); | |
84 | ||
85 | /* check version */ | |
86 | ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8U); | |
87 | if (CRYPT < ver) { | |
88 | return CRYPT_INVALID_PACKET; | |
89 | } | |
90 | ||
91 | /* check section and subsection */ | |
92 | if (section != (int)src[2] || subsection != (int)src[3]) { | |
93 | return CRYPT_INVALID_PACKET; | |
94 | } | |
95 | ||
96 | return CRYPT_OK; | |
97 | } | |
98 | ||
99 | ||
100 | /* max export size we'll encounter (smaller than this but lets round up a bit) */ | |
101 | #define DH_BUF_SIZE 1200 | |
102 | ||
103 | /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ | |
104 | static const struct { | |
105 | int size; | |
106 | char *name, *base, *prime; | |
107 | } sets[] = { | |
108 | #ifdef DH768 | |
109 | { | |
110 | 96, | |
111 | "DH-768", | |
112 | "4", | |
113 | "F///////////////////////////////////////////////////////////" | |
114 | "////////////////////////////////////////////////////////////" | |
115 | "//////m3wvV" | |
116 | }, | |
117 | #endif | |
118 | #ifdef DH1024 | |
119 | { | |
120 | 128, | |
121 | "DH-1024", | |
122 | "4", | |
123 | "F///////////////////////////////////////////////////////////" | |
124 | "////////////////////////////////////////////////////////////" | |
125 | "////////////////////////////////////////////////m3C47" | |
126 | }, | |
127 | #endif | |
128 | #ifdef DH1280 | |
129 | { | |
130 | 160, | |
131 | "DH-1280", | |
132 | "4", | |
133 | "F///////////////////////////////////////////////////////////" | |
134 | "////////////////////////////////////////////////////////////" | |
135 | "////////////////////////////////////////////////////////////" | |
136 | "//////////////////////////////m4kSN" | |
137 | }, | |
138 | #endif | |
139 | #ifdef DH1536 | |
140 | { | |
141 | 192, | |
142 | "DH-1536", | |
143 | "4", | |
144 | "F///////////////////////////////////////////////////////////" | |
145 | "////////////////////////////////////////////////////////////" | |
146 | "////////////////////////////////////////////////////////////" | |
147 | "////////////////////////////////////////////////////////////" | |
148 | "////////////m5uqd" | |
149 | }, | |
150 | #endif | |
151 | #ifdef DH1792 | |
152 | { | |
153 | 224, | |
154 | "DH-1792", | |
155 | "4", | |
156 | "F///////////////////////////////////////////////////////////" | |
157 | "////////////////////////////////////////////////////////////" | |
158 | "////////////////////////////////////////////////////////////" | |
159 | "////////////////////////////////////////////////////////////" | |
160 | "//////////////////////////////////////////////////////mT/sd" | |
161 | }, | |
162 | #endif | |
163 | #ifdef DH2048 | |
164 | { | |
165 | 256, | |
166 | "DH-2048", | |
167 | "4", | |
168 | "3///////////////////////////////////////////////////////////" | |
169 | "////////////////////////////////////////////////////////////" | |
170 | "////////////////////////////////////////////////////////////" | |
171 | "////////////////////////////////////////////////////////////" | |
172 | "////////////////////////////////////////////////////////////" | |
173 | "/////////////////////////////////////////m8MPh" | |
174 | }, | |
175 | #endif | |
176 | #ifdef DH2560 | |
177 | { | |
178 | 320, | |
179 | "DH-2560", | |
180 | "4", | |
181 | "3///////////////////////////////////////////////////////////" | |
182 | "////////////////////////////////////////////////////////////" | |
183 | "////////////////////////////////////////////////////////////" | |
184 | "////////////////////////////////////////////////////////////" | |
185 | "////////////////////////////////////////////////////////////" | |
186 | "////////////////////////////////////////////////////////////" | |
187 | "////////////////////////////////////////////////////////////" | |
188 | "/////mKFpF" | |
189 | }, | |
190 | #endif | |
191 | #ifdef DH3072 | |
192 | { | |
193 | 384, | |
194 | "DH-3072", | |
195 | "4", | |
196 | "3///////////////////////////////////////////////////////////" | |
197 | "////////////////////////////////////////////////////////////" | |
198 | "////////////////////////////////////////////////////////////" | |
199 | "////////////////////////////////////////////////////////////" | |
200 | "////////////////////////////////////////////////////////////" | |
201 | "////////////////////////////////////////////////////////////" | |
202 | "////////////////////////////////////////////////////////////" | |
203 | "////////////////////////////////////////////////////////////" | |
204 | "/////////////////////////////m32nN" | |
205 | }, | |
206 | #endif | |
207 | #ifdef DH4096 | |
208 | { | |
209 | 512, | |
210 | "DH-4096", | |
211 | "4", | |
212 | "////////////////////////////////////////////////////////////" | |
213 | "////////////////////////////////////////////////////////////" | |
214 | "////////////////////////////////////////////////////////////" | |
215 | "////////////////////////////////////////////////////////////" | |
216 | "////////////////////////////////////////////////////////////" | |
217 | "////////////////////////////////////////////////////////////" | |
218 | "////////////////////////////////////////////////////////////" | |
219 | "////////////////////////////////////////////////////////////" | |
220 | "////////////////////////////////////////////////////////////" | |
221 | "////////////////////////////////////////////////////////////" | |
222 | "////////////////////////////////////////////////////////////" | |
223 | "/////////////////////m8pOF" | |
224 | }, | |
225 | #endif | |
226 | { | |
227 | 0, | |
228 | NULL, | |
229 | NULL, | |
230 | NULL | |
231 | } | |
232 | }; | |
233 | ||
234 | static int is_valid_idx(int n) | |
235 | { | |
236 | int x; | |
237 | ||
238 | for (x = 0; sets[x].size; x++); | |
239 | if ((n < 0) || (n >= x)) { | |
240 | return 0; | |
241 | } | |
242 | return 1; | |
243 | } | |
16 | ||
17 | #ifdef LTC_MDH | |
18 | ||
19 | ||
20 | #include "dh_static.h" | |
244 | 21 | |
245 | 22 | /** |
246 | 23 | Test the DH sub-system (can take a while) |
317 | 94 | int dh_get_size(dh_key *key) |
318 | 95 | { |
319 | 96 | LTC_ARGCHK(key != NULL); |
320 | if (is_valid_idx(key->idx) == 1) { | |
97 | if (dh_is_valid_idx(key->idx) == 1) { | |
321 | 98 | return sets[key->idx].size; |
322 | 99 | } else { |
323 | 100 | return INT_MAX; /* large value that would cause dh_make_key() to fail */ |
366 | 143 | |
367 | 144 | /* make up random string */ |
368 | 145 | if ( rng_make_prng( keysize, wprng, prng, NULL) != CRYPT_OK) { |
369 | err = CRYPT_ERROR_READPRNG; | |
146 | err = CRYPT_ERROR_READPRNG; | |
370 | 147 | goto error2; |
371 | 148 | } |
372 | 149 | |
373 | 150 | if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) { |
374 | err = CRYPT_ERROR_READPRNG; | |
151 | err = CRYPT_ERROR_READPRNG; | |
375 | 152 | goto error2; |
376 | 153 | } |
377 | 154 | |
406 | 183 | /** |
407 | 184 | Free the allocated ram for a DH key |
408 | 185 | @param key The key which you wish to free |
409 | */ | |
186 | */ | |
410 | 187 | void dh_free(dh_key *key) |
411 | 188 | { |
412 | 189 | LTC_ARGCHK(key != NULL); |
441 | 218 | if (*outlen < (PACKET_SIZE + 2)) { |
442 | 219 | return CRYPT_BUFFER_OVERFLOW; |
443 | 220 | } |
444 | ||
221 | ||
445 | 222 | if (type == PK_PRIVATE && key->type != PK_PRIVATE) { |
446 | 223 | return CRYPT_PK_NOT_PRIVATE; |
447 | 224 | } |
522 | 299 | } |
523 | 300 | |
524 | 301 | /* is the key idx valid? */ |
525 | if (is_valid_idx(key->idx) != 1) { | |
302 | if (dh_is_valid_idx(key->idx) != 1) { | |
526 | 303 | err = CRYPT_PK_TYPE_MISMATCH; |
527 | 304 | goto error; |
528 | 305 | } |
549 | 326 | /** |
550 | 327 | Create a DH shared secret. |
551 | 328 | @param private_key The private DH key in the pair |
552 | @param public_key The public DH key in the pair | |
329 | @param public_key The public DH key in the pair | |
553 | 330 | @param out [out] The destination of the shared data |
554 | 331 | @param outlen [in/out] The max size and resulting size of the shared data. |
555 | 332 | @return CRYPT_OK if successful |
600 | 377 | return err; |
601 | 378 | } |
602 | 379 | |
603 | #include "dh_sys.c.inc" | |
604 | ||
605 | #endif | |
380 | #endif /* LTC_MDH */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file dh_static.c | |
14 | DH crypto, Tom St Denis | |
15 | */ | |
16 | ||
17 | #ifdef LTC_MDH | |
18 | ||
19 | #define __DECL_DH_STATIC_H__ | |
20 | #include "dh_static.h" | |
21 | ||
22 | /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ | |
23 | const dh_set sets[] = { | |
24 | #ifdef DH768 | |
25 | { | |
26 | 96, | |
27 | "DH-768", | |
28 | "4", | |
29 | "F///////////////////////////////////////////////////////////" | |
30 | "////////////////////////////////////////////////////////////" | |
31 | "//////m3wvV" | |
32 | }, | |
33 | #endif | |
34 | #ifdef DH1024 | |
35 | { | |
36 | 128, | |
37 | "DH-1024", | |
38 | "4", | |
39 | "F///////////////////////////////////////////////////////////" | |
40 | "////////////////////////////////////////////////////////////" | |
41 | "////////////////////////////////////////////////m3C47" | |
42 | }, | |
43 | #endif | |
44 | #ifdef DH1280 | |
45 | { | |
46 | 160, | |
47 | "DH-1280", | |
48 | "4", | |
49 | "F///////////////////////////////////////////////////////////" | |
50 | "////////////////////////////////////////////////////////////" | |
51 | "////////////////////////////////////////////////////////////" | |
52 | "//////////////////////////////m4kSN" | |
53 | }, | |
54 | #endif | |
55 | #ifdef DH1536 | |
56 | { | |
57 | 192, | |
58 | "DH-1536", | |
59 | "4", | |
60 | "F///////////////////////////////////////////////////////////" | |
61 | "////////////////////////////////////////////////////////////" | |
62 | "////////////////////////////////////////////////////////////" | |
63 | "////////////////////////////////////////////////////////////" | |
64 | "////////////m5uqd" | |
65 | }, | |
66 | #endif | |
67 | #ifdef DH1792 | |
68 | { | |
69 | 224, | |
70 | "DH-1792", | |
71 | "4", | |
72 | "F///////////////////////////////////////////////////////////" | |
73 | "////////////////////////////////////////////////////////////" | |
74 | "////////////////////////////////////////////////////////////" | |
75 | "////////////////////////////////////////////////////////////" | |
76 | "//////////////////////////////////////////////////////mT/sd" | |
77 | }, | |
78 | #endif | |
79 | #ifdef DH2048 | |
80 | { | |
81 | 256, | |
82 | "DH-2048", | |
83 | "4", | |
84 | "3///////////////////////////////////////////////////////////" | |
85 | "////////////////////////////////////////////////////////////" | |
86 | "////////////////////////////////////////////////////////////" | |
87 | "////////////////////////////////////////////////////////////" | |
88 | "////////////////////////////////////////////////////////////" | |
89 | "/////////////////////////////////////////m8MPh" | |
90 | }, | |
91 | #endif | |
92 | #ifdef DH2560 | |
93 | { | |
94 | 320, | |
95 | "DH-2560", | |
96 | "4", | |
97 | "3///////////////////////////////////////////////////////////" | |
98 | "////////////////////////////////////////////////////////////" | |
99 | "////////////////////////////////////////////////////////////" | |
100 | "////////////////////////////////////////////////////////////" | |
101 | "////////////////////////////////////////////////////////////" | |
102 | "////////////////////////////////////////////////////////////" | |
103 | "////////////////////////////////////////////////////////////" | |
104 | "/////mKFpF" | |
105 | }, | |
106 | #endif | |
107 | #ifdef DH3072 | |
108 | { | |
109 | 384, | |
110 | "DH-3072", | |
111 | "4", | |
112 | "3///////////////////////////////////////////////////////////" | |
113 | "////////////////////////////////////////////////////////////" | |
114 | "////////////////////////////////////////////////////////////" | |
115 | "////////////////////////////////////////////////////////////" | |
116 | "////////////////////////////////////////////////////////////" | |
117 | "////////////////////////////////////////////////////////////" | |
118 | "////////////////////////////////////////////////////////////" | |
119 | "////////////////////////////////////////////////////////////" | |
120 | "/////////////////////////////m32nN" | |
121 | }, | |
122 | #endif | |
123 | #ifdef DH4096 | |
124 | { | |
125 | 512, | |
126 | "DH-4096", | |
127 | "4", | |
128 | "////////////////////////////////////////////////////////////" | |
129 | "////////////////////////////////////////////////////////////" | |
130 | "////////////////////////////////////////////////////////////" | |
131 | "////////////////////////////////////////////////////////////" | |
132 | "////////////////////////////////////////////////////////////" | |
133 | "////////////////////////////////////////////////////////////" | |
134 | "////////////////////////////////////////////////////////////" | |
135 | "////////////////////////////////////////////////////////////" | |
136 | "////////////////////////////////////////////////////////////" | |
137 | "////////////////////////////////////////////////////////////" | |
138 | "////////////////////////////////////////////////////////////" | |
139 | "/////////////////////m8pOF" | |
140 | }, | |
141 | #endif | |
142 | { | |
143 | 0, | |
144 | NULL, | |
145 | NULL, | |
146 | NULL | |
147 | } | |
148 | }; | |
149 | ||
150 | int dh_is_valid_idx(int n) | |
151 | { | |
152 | int x; | |
153 | ||
154 | for (x = 0; sets[x].size; x++); | |
155 | if ((n < 0) || (n >= x)) { | |
156 | return 0; | |
157 | } | |
158 | return 1; | |
159 | } | |
160 | ||
161 | ||
162 | #endif /* LTC_MDH */ |
0 | #ifndef __DH_STATIC_H__ | |
1 | #define __DH_STATIC_H__ | |
2 | #ifndef __DECL_DH_STATIC_H__ | |
3 | #define __DECL_DH_STATIC_H__ extern | |
4 | #endif | |
5 | ||
6 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
7 | * | |
8 | * LibTomCrypt is a library that provides various cryptographic | |
9 | * algorithms in a highly modular and flexible manner. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org | |
15 | */ | |
16 | #include "tomcrypt.h" | |
17 | ||
18 | /** | |
19 | @file dh_static.h | |
20 | DH crypto, Tom St Denis | |
21 | */ | |
22 | ||
23 | #ifdef LTC_MDH | |
24 | ||
25 | /* size of a packet header in bytes */ | |
26 | #define PACKET_SIZE 4 | |
27 | ||
28 | /* Section tags */ | |
29 | #define PACKET_SECT_DH 1 | |
30 | ||
31 | /* Subsection Tags for the first three sections */ | |
32 | #define PACKET_SUB_KEY 0 | |
33 | #define PACKET_SUB_ENCRYPTED 1 | |
34 | #define PACKET_SUB_SIGNED 2 | |
35 | #define PACKET_SUB_ENC_KEY 3 | |
36 | ||
37 | #define OUTPUT_BIGNUM(num, out, y, z) \ | |
38 | { \ | |
39 | if ((y + 4) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ | |
40 | z = (unsigned long)mp_unsigned_bin_size(num); \ | |
41 | STORE32L(z, out+y); \ | |
42 | y += 4; \ | |
43 | if ((y + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ | |
44 | if ((err = mp_to_unsigned_bin(num, out+y)) != CRYPT_OK) { return err; } \ | |
45 | y += z; \ | |
46 | } | |
47 | ||
48 | #define INPUT_BIGNUM(num, in, x, y, inlen) \ | |
49 | { \ | |
50 | /* load value */ \ | |
51 | if ((y + 4) > inlen) { \ | |
52 | err = CRYPT_INVALID_PACKET; \ | |
53 | goto error; \ | |
54 | } \ | |
55 | LOAD32L(x, in+y); \ | |
56 | y += 4; \ | |
57 | \ | |
58 | /* sanity check... */ \ | |
59 | if ((x+y) > inlen) { \ | |
60 | err = CRYPT_INVALID_PACKET; \ | |
61 | goto error; \ | |
62 | } \ | |
63 | \ | |
64 | /* load it */ \ | |
65 | if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != CRYPT_OK) {\ | |
66 | goto error; \ | |
67 | } \ | |
68 | y += x; \ | |
69 | } | |
70 | ||
71 | static inline void packet_store_header (unsigned char *dst, int section, int subsection) | |
72 | { | |
73 | LTC_ARGCHK(dst != NULL); | |
74 | ||
75 | /* store version number */ | |
76 | dst[0] = (unsigned char)(CRYPT&255); | |
77 | dst[1] = (unsigned char)((CRYPT>>8)&255); | |
78 | ||
79 | /* store section and subsection */ | |
80 | dst[2] = (unsigned char)(section & 255); | |
81 | dst[3] = (unsigned char)(subsection & 255); | |
82 | ||
83 | } | |
84 | ||
85 | static inline int packet_valid_header (unsigned char *src, int section, int subsection) | |
86 | { | |
87 | unsigned long ver; | |
88 | ||
89 | LTC_ARGCHK(src != NULL); | |
90 | ||
91 | /* check version */ | |
92 | ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8U); | |
93 | if (CRYPT < ver) { | |
94 | return CRYPT_INVALID_PACKET; | |
95 | } | |
96 | ||
97 | /* check section and subsection */ | |
98 | if (section != (int)src[2] || subsection != (int)src[3]) { | |
99 | return CRYPT_INVALID_PACKET; | |
100 | } | |
101 | ||
102 | return CRYPT_OK; | |
103 | } | |
104 | ||
105 | #ifndef DH_BUF_SIZE | |
106 | /* max export size we'll encounter (smaller than this but lets round up a bit) */ | |
107 | #define DH_BUF_SIZE 1200 | |
108 | #endif /* DH_BUF_SIZE */ | |
109 | ||
110 | typedef struct { | |
111 | int size; | |
112 | char *name, *base, *prime; | |
113 | } dh_set; | |
114 | ||
115 | /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ | |
116 | __DECL_DH_STATIC_H__ const dh_set sets[]; | |
117 | ||
118 | ||
119 | int dh_is_valid_idx(int n); | |
120 | ||
121 | ||
122 | #endif /* __DH_STATIC_H__ */ | |
123 | ||
124 | #endif /* LTC_MDH */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org | |
9 | */ | |
10 | ||
11 | #include "tomcrypt.h" | |
12 | ||
13 | #ifdef LTC_MDH | |
14 | /** | |
15 | @file dh_sys.c | |
16 | DH Crypto, Tom St Denis | |
17 | */ | |
18 | ||
19 | #include "dh_static.h" | |
20 | ||
21 | ||
22 | /** | |
23 | Encrypt a short symmetric key with a public DH key | |
24 | @param in The symmetric key to encrypt | |
25 | @param inlen The length of the key (octets) | |
26 | @param out [out] The ciphertext | |
27 | @param outlen [in/out] The max size and resulting size of the ciphertext | |
28 | @param prng An active PRNG state | |
29 | @param wprng The index of the PRNG desired | |
30 | @param hash The index of the hash desired (must produce a digest of size >= the size of the plaintext) | |
31 | @param key The public key you wish to encrypt with. | |
32 | @return CRYPT_OK if successful | |
33 | */ | |
34 | int dh_encrypt_key(const unsigned char *in, unsigned long inlen, | |
35 | unsigned char *out, unsigned long *outlen, | |
36 | prng_state *prng, int wprng, int hash, | |
37 | dh_key *key) | |
38 | { | |
39 | unsigned char *pub_expt, *dh_shared, *skey; | |
40 | dh_key pubkey; | |
41 | unsigned long x, y, z, pubkeysize; | |
42 | int err; | |
43 | ||
44 | LTC_ARGCHK(in != NULL); | |
45 | LTC_ARGCHK(out != NULL); | |
46 | LTC_ARGCHK(outlen != NULL); | |
47 | LTC_ARGCHK(key != NULL); | |
48 | ||
49 | /* check that wprng/hash are not invalid */ | |
50 | if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | |
51 | return err; | |
52 | } | |
53 | ||
54 | if ((err = hash_is_valid(hash)) != CRYPT_OK) { | |
55 | return err; | |
56 | } | |
57 | ||
58 | if (inlen > hash_descriptor[hash].hashsize) { | |
59 | return CRYPT_INVALID_HASH; | |
60 | } | |
61 | ||
62 | /* allocate memory */ | |
63 | pub_expt = XMALLOC(DH_BUF_SIZE); | |
64 | dh_shared = XMALLOC(DH_BUF_SIZE); | |
65 | skey = XMALLOC(MAXBLOCKSIZE); | |
66 | if (pub_expt == NULL || dh_shared == NULL || skey == NULL) { | |
67 | if (pub_expt != NULL) { | |
68 | XFREE(pub_expt); | |
69 | } | |
70 | if (dh_shared != NULL) { | |
71 | XFREE(dh_shared); | |
72 | } | |
73 | if (skey != NULL) { | |
74 | XFREE(skey); | |
75 | } | |
76 | return CRYPT_MEM; | |
77 | } | |
78 | ||
79 | /* make a random key and export the public copy */ | |
80 | if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) { | |
81 | goto LBL_ERR; | |
82 | } | |
83 | ||
84 | pubkeysize = DH_BUF_SIZE; | |
85 | if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { | |
86 | dh_free(&pubkey); | |
87 | goto LBL_ERR; | |
88 | } | |
89 | ||
90 | /* now check if the out buffer is big enough */ | |
91 | if (*outlen < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + inlen)) { | |
92 | dh_free(&pubkey); | |
93 | err = CRYPT_BUFFER_OVERFLOW; | |
94 | goto LBL_ERR; | |
95 | } | |
96 | ||
97 | x = DH_BUF_SIZE; | |
98 | if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) { | |
99 | dh_free(&pubkey); | |
100 | goto LBL_ERR; | |
101 | } | |
102 | dh_free(&pubkey); | |
103 | ||
104 | z = MAXBLOCKSIZE; | |
105 | if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) { | |
106 | goto LBL_ERR; | |
107 | } | |
108 | ||
109 | /* store header */ | |
110 | packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY); | |
111 | ||
112 | /* output header */ | |
113 | y = PACKET_SIZE; | |
114 | ||
115 | /* size of hash name and the name itself */ | |
116 | out[y++] = hash_descriptor[hash].ID; | |
117 | ||
118 | /* length of DH pubkey and the key itself */ | |
119 | STORE32L(pubkeysize, out+y); | |
120 | y += 4; | |
121 | for (x = 0; x < pubkeysize; x++, y++) { | |
122 | out[y] = pub_expt[x]; | |
123 | } | |
124 | ||
125 | /* Store the encrypted key */ | |
126 | STORE32L(inlen, out+y); | |
127 | y += 4; | |
128 | ||
129 | for (x = 0; x < inlen; x++, y++) { | |
130 | out[y] = skey[x] ^ in[x]; | |
131 | } | |
132 | *outlen = y; | |
133 | ||
134 | err = CRYPT_OK; | |
135 | LBL_ERR: | |
136 | #ifdef LTC_CLEAN_STACK | |
137 | /* clean up */ | |
138 | zeromem(pub_expt, DH_BUF_SIZE); | |
139 | zeromem(dh_shared, DH_BUF_SIZE); | |
140 | zeromem(skey, MAXBLOCKSIZE); | |
141 | #endif | |
142 | XFREE(skey); | |
143 | XFREE(dh_shared); | |
144 | XFREE(pub_expt); | |
145 | ||
146 | return err; | |
147 | } | |
148 | ||
149 | /** | |
150 | Decrypt a DH encrypted symmetric key | |
151 | @param in The DH encrypted packet | |
152 | @param inlen The length of the DH encrypted packet | |
153 | @param out The plaintext | |
154 | @param outlen [in/out] The max size and resulting size of the plaintext | |
155 | @param key The private DH key corresponding to the public key that encrypted the plaintext | |
156 | @return CRYPT_OK if successful | |
157 | */ | |
158 | int dh_decrypt_key(const unsigned char *in, unsigned long inlen, | |
159 | unsigned char *out, unsigned long *outlen, | |
160 | dh_key *key) | |
161 | { | |
162 | unsigned char *shared_secret, *skey; | |
163 | unsigned long x, y, z, keysize; | |
164 | int hash, err; | |
165 | dh_key pubkey; | |
166 | ||
167 | LTC_ARGCHK(in != NULL); | |
168 | LTC_ARGCHK(out != NULL); | |
169 | LTC_ARGCHK(outlen != NULL); | |
170 | LTC_ARGCHK(key != NULL); | |
171 | ||
172 | /* right key type? */ | |
173 | if (key->type != PK_PRIVATE) { | |
174 | return CRYPT_PK_NOT_PRIVATE; | |
175 | } | |
176 | ||
177 | /* allocate ram */ | |
178 | shared_secret = XMALLOC(DH_BUF_SIZE); | |
179 | skey = XMALLOC(MAXBLOCKSIZE); | |
180 | if (shared_secret == NULL || skey == NULL) { | |
181 | if (shared_secret != NULL) { | |
182 | XFREE(shared_secret); | |
183 | } | |
184 | if (skey != NULL) { | |
185 | XFREE(skey); | |
186 | } | |
187 | return CRYPT_MEM; | |
188 | } | |
189 | ||
190 | /* check if initial header should fit */ | |
191 | if (inlen < PACKET_SIZE+1+4+4) { | |
192 | err = CRYPT_INVALID_PACKET; | |
193 | goto LBL_ERR; | |
194 | } else { | |
195 | inlen -= PACKET_SIZE+1+4+4; | |
196 | } | |
197 | ||
198 | /* is header correct? */ | |
199 | if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { | |
200 | goto LBL_ERR; | |
201 | } | |
202 | ||
203 | /* now lets get the hash name */ | |
204 | y = PACKET_SIZE; | |
205 | hash = find_hash_id(in[y++]); | |
206 | if (hash == -1) { | |
207 | err = CRYPT_INVALID_HASH; | |
208 | goto LBL_ERR; | |
209 | } | |
210 | ||
211 | /* get public key */ | |
212 | LOAD32L(x, in+y); | |
213 | ||
214 | /* now check if the imported key will fit */ | |
215 | if (inlen < x) { | |
216 | err = CRYPT_INVALID_PACKET; | |
217 | goto LBL_ERR; | |
218 | } else { | |
219 | inlen -= x; | |
220 | } | |
221 | ||
222 | y += 4; | |
223 | if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) { | |
224 | goto LBL_ERR; | |
225 | } | |
226 | y += x; | |
227 | ||
228 | /* make shared key */ | |
229 | x = DH_BUF_SIZE; | |
230 | if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { | |
231 | dh_free(&pubkey); | |
232 | goto LBL_ERR; | |
233 | } | |
234 | dh_free(&pubkey); | |
235 | ||
236 | z = MAXBLOCKSIZE; | |
237 | if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { | |
238 | goto LBL_ERR; | |
239 | } | |
240 | ||
241 | /* load in the encrypted key */ | |
242 | LOAD32L(keysize, in+y); | |
243 | ||
244 | /* will the out fit as part of the input */ | |
245 | if (inlen < keysize) { | |
246 | err = CRYPT_INVALID_PACKET; | |
247 | goto LBL_ERR; | |
248 | } else { | |
249 | inlen -= keysize; | |
250 | } | |
251 | ||
252 | if (keysize > *outlen) { | |
253 | err = CRYPT_BUFFER_OVERFLOW; | |
254 | goto LBL_ERR; | |
255 | } | |
256 | y += 4; | |
257 | ||
258 | *outlen = keysize; | |
259 | ||
260 | for (x = 0; x < keysize; x++, y++) { | |
261 | out[x] = skey[x] ^ in[y]; | |
262 | } | |
263 | ||
264 | err = CRYPT_OK; | |
265 | LBL_ERR: | |
266 | #ifdef LTC_CLEAN_STACK | |
267 | zeromem(shared_secret, DH_BUF_SIZE); | |
268 | zeromem(skey, MAXBLOCKSIZE); | |
269 | #endif | |
270 | ||
271 | XFREE(skey); | |
272 | XFREE(shared_secret); | |
273 | ||
274 | return err; | |
275 | } | |
276 | ||
277 | /* perform an ElGamal Signature of a hash | |
278 | * | |
279 | * The math works as follows. x is the private key, M is the message to sign | |
280 | ||
281 | 1. pick a random k | |
282 | 2. compute a = g^k mod p | |
283 | 3. compute b = (M - xa)/k mod p | |
284 | 4. Send (a,b) | |
285 | ||
286 | Now to verify with y=g^x mod p, a and b | |
287 | ||
288 | 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k) | |
289 | = g^(xa + (M - xa)) | |
290 | = g^M [all mod p] | |
291 | ||
292 | 2. Compare against g^M mod p [based on input hash]. | |
293 | 3. If result of #2 == result of #1 then signature valid | |
294 | */ | |
295 | ||
296 | /** | |
297 | Sign a message digest using a DH private key | |
298 | @param in The data to sign | |
299 | @param inlen The length of the input (octets) | |
300 | @param out [out] The destination of the signature | |
301 | @param outlen [in/out] The max size and resulting size of the output | |
302 | @param prng An active PRNG state | |
303 | @param wprng The index of the PRNG desired | |
304 | @param key A private DH key | |
305 | @return CRYPT_OK if successful | |
306 | */ | |
307 | int dh_sign_hash(const unsigned char *in, unsigned long inlen, | |
308 | unsigned char *out, unsigned long *outlen, | |
309 | prng_state *prng, int wprng, dh_key *key) | |
310 | { | |
311 | void *a, *b, *k, *m, *g, *p, *p1, *tmp; | |
312 | unsigned char *buf; | |
313 | unsigned long x, y; | |
314 | int err; | |
315 | ||
316 | LTC_ARGCHK(in != NULL); | |
317 | LTC_ARGCHK(out != NULL); | |
318 | LTC_ARGCHK(outlen != NULL); | |
319 | LTC_ARGCHK(key != NULL); | |
320 | ||
321 | /* check parameters */ | |
322 | if (key->type != PK_PRIVATE) { | |
323 | return CRYPT_PK_NOT_PRIVATE; | |
324 | } | |
325 | ||
326 | if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | |
327 | return err; | |
328 | } | |
329 | ||
330 | /* is the IDX valid ? */ | |
331 | if (dh_is_valid_idx(key->idx) != 1) { | |
332 | return CRYPT_PK_INVALID_TYPE; | |
333 | } | |
334 | ||
335 | /* allocate ram for buf */ | |
336 | buf = XMALLOC(520); | |
337 | ||
338 | /* make up a random value k, | |
339 | * since the order of the group is prime | |
340 | * we need not check if gcd(k, r) is 1 | |
341 | */ | |
342 | if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) != | |
343 | (unsigned long)(sets[key->idx].size)) { | |
344 | err = CRYPT_ERROR_READPRNG; | |
345 | goto LBL_ERR_1; | |
346 | } | |
347 | ||
348 | /* init bignums */ | |
349 | if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != CRYPT_OK) { | |
350 | goto LBL_ERR; | |
351 | } | |
352 | ||
353 | /* load k and m */ | |
354 | if ((err = mp_read_unsigned_bin(m, (unsigned char *)in, inlen)) != CRYPT_OK) { goto LBL_ERR; } | |
355 | if ((err = mp_read_unsigned_bin(k, buf, sets[key->idx].size)) != CRYPT_OK) { goto LBL_ERR; } | |
356 | ||
357 | /* load g, p and p1 */ | |
358 | if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto LBL_ERR; } | |
359 | if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto LBL_ERR; } | |
360 | if ((err = mp_sub_d(p, 1, p1)) != CRYPT_OK) { goto LBL_ERR; } | |
361 | if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto LBL_ERR; } /* p1 = (p-1)/2 */ | |
362 | ||
363 | /* now get a = g^k mod p */ | |
364 | if ((err = mp_exptmod(g, k, p, a)) != CRYPT_OK) { goto LBL_ERR; } | |
365 | ||
366 | /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */ | |
367 | if ((err = mp_invmod(k, p1, k)) != CRYPT_OK) { goto LBL_ERR; } /* k = 1/k mod p1 */ | |
368 | if ((err = mp_mulmod(a, key->x, p1, tmp)) != CRYPT_OK) { goto LBL_ERR; } /* tmp = xa */ | |
369 | if ((err = mp_submod(m, tmp, p1, tmp)) != CRYPT_OK) { goto LBL_ERR; } /* tmp = M - xa */ | |
370 | if ((err = mp_mulmod(k, tmp, p1, b)) != CRYPT_OK) { goto LBL_ERR; } /* b = (M - xa)/k */ | |
371 | ||
372 | /* check for overflow */ | |
373 | if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(a) + mp_unsigned_bin_size(b)) > *outlen) { | |
374 | err = CRYPT_BUFFER_OVERFLOW; | |
375 | goto LBL_ERR; | |
376 | } | |
377 | ||
378 | /* store header */ | |
379 | y = PACKET_SIZE; | |
380 | ||
381 | /* now store them both (a,b) */ | |
382 | x = (unsigned long)mp_unsigned_bin_size(a); | |
383 | STORE32L(x, out+y); y += 4; | |
384 | if ((err = mp_to_unsigned_bin(a, out+y)) != CRYPT_OK) { goto LBL_ERR; } | |
385 | y += x; | |
386 | ||
387 | x = (unsigned long)mp_unsigned_bin_size(b); | |
388 | STORE32L(x, out+y); y += 4; | |
389 | if ((err = mp_to_unsigned_bin(b, out+y)) != CRYPT_OK) { goto LBL_ERR; } | |
390 | y += x; | |
391 | ||
392 | /* check if size too big */ | |
393 | if (*outlen < y) { | |
394 | err = CRYPT_BUFFER_OVERFLOW; | |
395 | goto LBL_ERR; | |
396 | } | |
397 | ||
398 | /* store header */ | |
399 | packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED); | |
400 | *outlen = y; | |
401 | ||
402 | err = CRYPT_OK; | |
403 | LBL_ERR: | |
404 | mp_clear_multi(tmp, p1, g, p, m, k, b, a, NULL); | |
405 | LBL_ERR_1: | |
406 | ||
407 | XFREE(buf); | |
408 | ||
409 | return err; | |
410 | } | |
411 | ||
412 | ||
413 | /** | |
414 | Verify the signature given | |
415 | @param sig The signature | |
416 | @param siglen The length of the signature (octets) | |
417 | @param hash The hash that was signed | |
418 | @param hashlen The length of the hash (octets) | |
419 | @param stat [out] Result of signature comparison, 1==valid, 0==invalid | |
420 | @param key The public DH key that signed the hash | |
421 | @return CRYPT_OK if succsessful (even if signature is invalid) | |
422 | */ | |
423 | int dh_verify_hash(const unsigned char *sig, unsigned long siglen, | |
424 | const unsigned char *hash, unsigned long hashlen, | |
425 | int *stat, dh_key *key) | |
426 | { | |
427 | void *a, *b, *p, *g, *m, *tmp; | |
428 | unsigned long x, y; | |
429 | int err; | |
430 | ||
431 | LTC_ARGCHK(sig != NULL); | |
432 | LTC_ARGCHK(hash != NULL); | |
433 | LTC_ARGCHK(stat != NULL); | |
434 | LTC_ARGCHK(key != NULL); | |
435 | ||
436 | /* default to invalid */ | |
437 | *stat = 0; | |
438 | ||
439 | /* check initial input length */ | |
440 | if (siglen < PACKET_SIZE+4+4) { | |
441 | return CRYPT_INVALID_PACKET; | |
442 | } | |
443 | ||
444 | /* header ok? */ | |
445 | if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) { | |
446 | return err; | |
447 | } | |
448 | ||
449 | /* get hash out of packet */ | |
450 | y = PACKET_SIZE; | |
451 | ||
452 | /* init all bignums */ | |
453 | if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != CRYPT_OK) { | |
454 | return err; | |
455 | } | |
456 | ||
457 | /* load a and b */ | |
458 | INPUT_BIGNUM(a, sig, x, y, siglen); | |
459 | INPUT_BIGNUM(b, sig, x, y, siglen); | |
460 | ||
461 | /* load p and g */ | |
462 | if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error1; } | |
463 | if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error1; } | |
464 | ||
465 | /* load m */ | |
466 | if ((err = mp_read_unsigned_bin(m, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error1; } | |
467 | ||
468 | /* find g^m mod p */ | |
469 | if ((err = mp_exptmod(g, m, p, m)) != CRYPT_OK) { goto error1; } /* m = g^m mod p */ | |
470 | ||
471 | /* find y^a * a^b */ | |
472 | if ((err = mp_exptmod(key->y, a, p, tmp)) != CRYPT_OK) { goto error1; } /* tmp = y^a mod p */ | |
473 | if ((err = mp_exptmod(a, b, p, a)) != CRYPT_OK) { goto error1; } /* a = a^b mod p */ | |
474 | if ((err = mp_mulmod(a, tmp, p, a)) != CRYPT_OK) { goto error1; } /* a = y^a * a^b mod p */ | |
475 | ||
476 | /* y^a * a^b == g^m ??? */ | |
477 | if (mp_cmp(a, m) == 0) { | |
478 | *stat = 1; | |
479 | } | |
480 | ||
481 | /* clean up */ | |
482 | err = CRYPT_OK; | |
483 | goto done; | |
484 | error1: | |
485 | error: | |
486 | done: | |
487 | mp_clear_multi(tmp, m, g, p, b, a, NULL); | |
488 | return err; | |
489 | } | |
490 | ||
491 | #endif /* LTC_MDH */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org | |
9 | */ | |
10 | ||
11 | /** | |
12 | @file dh_sys.c | |
13 | DH Crypto, Tom St Denis | |
14 | */ | |
15 | ||
16 | /** | |
17 | Encrypt a short symmetric key with a public DH key | |
18 | @param in The symmetric key to encrypt | |
19 | @param inlen The length of the key (octets) | |
20 | @param out [out] The ciphertext | |
21 | @param outlen [in/out] The max size and resulting size of the ciphertext | |
22 | @param prng An active PRNG state | |
23 | @param wprng The index of the PRNG desired | |
24 | @param hash The index of the hash desired (must produce a digest of size >= the size of the plaintext) | |
25 | @param key The public key you wish to encrypt with. | |
26 | @return CRYPT_OK if successful | |
27 | */ | |
28 | int dh_encrypt_key(const unsigned char *in, unsigned long inlen, | |
29 | unsigned char *out, unsigned long *outlen, | |
30 | prng_state *prng, int wprng, int hash, | |
31 | dh_key *key) | |
32 | { | |
33 | unsigned char *pub_expt, *dh_shared, *skey; | |
34 | dh_key pubkey; | |
35 | unsigned long x, y, z, pubkeysize; | |
36 | int err; | |
37 | ||
38 | LTC_ARGCHK(in != NULL); | |
39 | LTC_ARGCHK(out != NULL); | |
40 | LTC_ARGCHK(outlen != NULL); | |
41 | LTC_ARGCHK(key != NULL); | |
42 | ||
43 | /* check that wprng/hash are not invalid */ | |
44 | if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | |
45 | return err; | |
46 | } | |
47 | ||
48 | if ((err = hash_is_valid(hash)) != CRYPT_OK) { | |
49 | return err; | |
50 | } | |
51 | ||
52 | if (inlen > hash_descriptor[hash].hashsize) { | |
53 | return CRYPT_INVALID_HASH; | |
54 | } | |
55 | ||
56 | /* allocate memory */ | |
57 | pub_expt = XMALLOC(DH_BUF_SIZE); | |
58 | dh_shared = XMALLOC(DH_BUF_SIZE); | |
59 | skey = XMALLOC(MAXBLOCKSIZE); | |
60 | if (pub_expt == NULL || dh_shared == NULL || skey == NULL) { | |
61 | if (pub_expt != NULL) { | |
62 | XFREE(pub_expt); | |
63 | } | |
64 | if (dh_shared != NULL) { | |
65 | XFREE(dh_shared); | |
66 | } | |
67 | if (skey != NULL) { | |
68 | XFREE(skey); | |
69 | } | |
70 | return CRYPT_MEM; | |
71 | } | |
72 | ||
73 | /* make a random key and export the public copy */ | |
74 | if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) { | |
75 | goto LBL_ERR; | |
76 | } | |
77 | ||
78 | pubkeysize = DH_BUF_SIZE; | |
79 | if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { | |
80 | dh_free(&pubkey); | |
81 | goto LBL_ERR; | |
82 | } | |
83 | ||
84 | /* now check if the out buffer is big enough */ | |
85 | if (*outlen < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + inlen)) { | |
86 | dh_free(&pubkey); | |
87 | err = CRYPT_BUFFER_OVERFLOW; | |
88 | goto LBL_ERR; | |
89 | } | |
90 | ||
91 | /* make random key */ | |
92 | ||
93 | x = DH_BUF_SIZE; | |
94 | if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) { | |
95 | dh_free(&pubkey); | |
96 | goto LBL_ERR; | |
97 | } | |
98 | dh_free(&pubkey); | |
99 | ||
100 | z = MAXBLOCKSIZE; | |
101 | if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) { | |
102 | goto LBL_ERR; | |
103 | } | |
104 | ||
105 | /* store header */ | |
106 | packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY); | |
107 | ||
108 | /* output header */ | |
109 | y = PACKET_SIZE; | |
110 | ||
111 | /* size of hash name and the name itself */ | |
112 | out[y++] = hash_descriptor[hash].ID; | |
113 | ||
114 | /* length of DH pubkey and the key itself */ | |
115 | STORE32L(pubkeysize, out+y); | |
116 | y += 4; | |
117 | for (x = 0; x < pubkeysize; x++, y++) { | |
118 | out[y] = pub_expt[x]; | |
119 | } | |
120 | ||
121 | /* Store the encrypted key */ | |
122 | STORE32L(inlen, out+y); | |
123 | y += 4; | |
124 | ||
125 | for (x = 0; x < inlen; x++, y++) { | |
126 | out[y] = skey[x] ^ in[x]; | |
127 | } | |
128 | *outlen = y; | |
129 | ||
130 | err = CRYPT_OK; | |
131 | LBL_ERR: | |
132 | #ifdef LTC_CLEAN_STACK | |
133 | /* clean up */ | |
134 | zeromem(pub_expt, DH_BUF_SIZE); | |
135 | zeromem(dh_shared, DH_BUF_SIZE); | |
136 | zeromem(skey, MAXBLOCKSIZE); | |
137 | #endif | |
138 | XFREE(skey); | |
139 | XFREE(dh_shared); | |
140 | XFREE(pub_expt); | |
141 | ||
142 | return err; | |
143 | } | |
144 | ||
145 | /** | |
146 | Decrypt a DH encrypted symmetric key | |
147 | @param in The DH encrypted packet | |
148 | @param inlen The length of the DH encrypted packet | |
149 | @param out The plaintext | |
150 | @param outlen [in/out] The max size and resulting size of the plaintext | |
151 | @param key The private DH key corresponding to the public key that encrypted the plaintext | |
152 | @return CRYPT_OK if successful | |
153 | */ | |
154 | int dh_decrypt_key(const unsigned char *in, unsigned long inlen, | |
155 | unsigned char *out, unsigned long *outlen, | |
156 | dh_key *key) | |
157 | { | |
158 | unsigned char *shared_secret, *skey; | |
159 | unsigned long x, y, z, keysize; | |
160 | int hash, err; | |
161 | dh_key pubkey; | |
162 | ||
163 | LTC_ARGCHK(in != NULL); | |
164 | LTC_ARGCHK(out != NULL); | |
165 | LTC_ARGCHK(outlen != NULL); | |
166 | LTC_ARGCHK(key != NULL); | |
167 | ||
168 | /* right key type? */ | |
169 | if (key->type != PK_PRIVATE) { | |
170 | return CRYPT_PK_NOT_PRIVATE; | |
171 | } | |
172 | ||
173 | /* allocate ram */ | |
174 | shared_secret = XMALLOC(DH_BUF_SIZE); | |
175 | skey = XMALLOC(MAXBLOCKSIZE); | |
176 | if (shared_secret == NULL || skey == NULL) { | |
177 | if (shared_secret != NULL) { | |
178 | XFREE(shared_secret); | |
179 | } | |
180 | if (skey != NULL) { | |
181 | XFREE(skey); | |
182 | } | |
183 | return CRYPT_MEM; | |
184 | } | |
185 | ||
186 | /* check if initial header should fit */ | |
187 | if (inlen < PACKET_SIZE+1+4+4) { | |
188 | err = CRYPT_INVALID_PACKET; | |
189 | goto LBL_ERR; | |
190 | } else { | |
191 | inlen -= PACKET_SIZE+1+4+4; | |
192 | } | |
193 | ||
194 | /* is header correct? */ | |
195 | if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { | |
196 | goto LBL_ERR; | |
197 | } | |
198 | ||
199 | /* now lets get the hash name */ | |
200 | y = PACKET_SIZE; | |
201 | hash = find_hash_id(in[y++]); | |
202 | if (hash == -1) { | |
203 | err = CRYPT_INVALID_HASH; | |
204 | goto LBL_ERR; | |
205 | } | |
206 | ||
207 | /* get public key */ | |
208 | LOAD32L(x, in+y); | |
209 | ||
210 | /* now check if the imported key will fit */ | |
211 | if (inlen < x) { | |
212 | err = CRYPT_INVALID_PACKET; | |
213 | goto LBL_ERR; | |
214 | } else { | |
215 | inlen -= x; | |
216 | } | |
217 | ||
218 | y += 4; | |
219 | if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) { | |
220 | goto LBL_ERR; | |
221 | } | |
222 | y += x; | |
223 | ||
224 | /* make shared key */ | |
225 | x = DH_BUF_SIZE; | |
226 | if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { | |
227 | dh_free(&pubkey); | |
228 | goto LBL_ERR; | |
229 | } | |
230 | dh_free(&pubkey); | |
231 | ||
232 | z = MAXBLOCKSIZE; | |
233 | if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { | |
234 | goto LBL_ERR; | |
235 | } | |
236 | ||
237 | /* load in the encrypted key */ | |
238 | LOAD32L(keysize, in+y); | |
239 | ||
240 | /* will the out fit as part of the input */ | |
241 | if (inlen < keysize) { | |
242 | err = CRYPT_INVALID_PACKET; | |
243 | goto LBL_ERR; | |
244 | } else { | |
245 | inlen -= keysize; | |
246 | } | |
247 | ||
248 | if (keysize > *outlen) { | |
249 | err = CRYPT_BUFFER_OVERFLOW; | |
250 | goto LBL_ERR; | |
251 | } | |
252 | y += 4; | |
253 | ||
254 | *outlen = keysize; | |
255 | ||
256 | for (x = 0; x < keysize; x++, y++) { | |
257 | out[x] = skey[x] ^ in[y]; | |
258 | } | |
259 | ||
260 | err = CRYPT_OK; | |
261 | LBL_ERR: | |
262 | #ifdef LTC_CLEAN_STACK | |
263 | zeromem(shared_secret, DH_BUF_SIZE); | |
264 | zeromem(skey, MAXBLOCKSIZE); | |
265 | #endif | |
266 | ||
267 | XFREE(skey); | |
268 | XFREE(shared_secret); | |
269 | ||
270 | return err; | |
271 | } | |
272 | ||
273 | /* perform an ElGamal Signature of a hash | |
274 | * | |
275 | * The math works as follows. x is the private key, M is the message to sign | |
276 | ||
277 | 1. pick a random k | |
278 | 2. compute a = g^k mod p | |
279 | 3. compute b = (M - xa)/k mod p | |
280 | 4. Send (a,b) | |
281 | ||
282 | Now to verify with y=g^x mod p, a and b | |
283 | ||
284 | 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k) | |
285 | = g^(xa + (M - xa)) | |
286 | = g^M [all mod p] | |
287 | ||
288 | 2. Compare against g^M mod p [based on input hash]. | |
289 | 3. If result of #2 == result of #1 then signature valid | |
290 | */ | |
291 | ||
292 | /** | |
293 | Sign a message digest using a DH private key | |
294 | @param in The data to sign | |
295 | @param inlen The length of the input (octets) | |
296 | @param out [out] The destination of the signature | |
297 | @param outlen [in/out] The max size and resulting size of the output | |
298 | @param prng An active PRNG state | |
299 | @param wprng The index of the PRNG desired | |
300 | @param key A private DH key | |
301 | @return CRYPT_OK if successful | |
302 | */ | |
303 | int dh_sign_hash(const unsigned char *in, unsigned long inlen, | |
304 | unsigned char *out, unsigned long *outlen, | |
305 | prng_state *prng, int wprng, dh_key *key) | |
306 | { | |
307 | void *a, *b, *k, *m, *g, *p, *p1, *tmp; | |
308 | unsigned char *buf; | |
309 | unsigned long x, y; | |
310 | int err; | |
311 | ||
312 | LTC_ARGCHK(in != NULL); | |
313 | LTC_ARGCHK(out != NULL); | |
314 | LTC_ARGCHK(outlen != NULL); | |
315 | LTC_ARGCHK(key != NULL); | |
316 | ||
317 | /* check parameters */ | |
318 | if (key->type != PK_PRIVATE) { | |
319 | return CRYPT_PK_NOT_PRIVATE; | |
320 | } | |
321 | ||
322 | if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | |
323 | return err; | |
324 | } | |
325 | ||
326 | /* is the IDX valid ? */ | |
327 | if (is_valid_idx(key->idx) != 1) { | |
328 | return CRYPT_PK_INVALID_TYPE; | |
329 | } | |
330 | ||
331 | /* allocate ram for buf */ | |
332 | buf = XMALLOC(520); | |
333 | ||
334 | /* make up a random value k, | |
335 | * since the order of the group is prime | |
336 | * we need not check if gcd(k, r) is 1 | |
337 | */ | |
338 | if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) != | |
339 | (unsigned long)(sets[key->idx].size)) { | |
340 | err = CRYPT_ERROR_READPRNG; | |
341 | goto LBL_ERR; | |
342 | } | |
343 | ||
344 | /* init bignums */ | |
345 | if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != CRYPT_OK) { | |
346 | goto LBL_ERR; | |
347 | } | |
348 | ||
349 | /* load k and m */ | |
350 | if ((err = mp_read_unsigned_bin(m, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; } | |
351 | if ((err = mp_read_unsigned_bin(k, buf, sets[key->idx].size)) != CRYPT_OK) { goto error; } | |
352 | ||
353 | /* load g, p and p1 */ | |
354 | if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; } | |
355 | if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; } | |
356 | if ((err = mp_sub_d(p, 1, p1)) != CRYPT_OK) { goto error; } | |
357 | if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto error; } /* p1 = (p-1)/2 */ | |
358 | ||
359 | /* now get a = g^k mod p */ | |
360 | if ((err = mp_exptmod(g, k, p, a)) != CRYPT_OK) { goto error; } | |
361 | ||
362 | /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */ | |
363 | if ((err = mp_invmod(k, p1, k)) != CRYPT_OK) { goto error; } /* k = 1/k mod p1 */ | |
364 | if ((err = mp_mulmod(a, key->x, p1, tmp)) != CRYPT_OK) { goto error; } /* tmp = xa */ | |
365 | if ((err = mp_submod(m, tmp, p1, tmp)) != CRYPT_OK) { goto error; } /* tmp = M - xa */ | |
366 | if ((err = mp_mulmod(k, tmp, p1, b)) != CRYPT_OK) { goto error; } /* b = (M - xa)/k */ | |
367 | ||
368 | /* check for overflow */ | |
369 | if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(a) + mp_unsigned_bin_size(b)) > *outlen) { | |
370 | err = CRYPT_BUFFER_OVERFLOW; | |
371 | goto LBL_ERR; | |
372 | } | |
373 | ||
374 | /* store header */ | |
375 | y = PACKET_SIZE; | |
376 | ||
377 | /* now store them both (a,b) */ | |
378 | x = (unsigned long)mp_unsigned_bin_size(a); | |
379 | STORE32L(x, out+y); y += 4; | |
380 | if ((err = mp_to_unsigned_bin(a, out+y)) != CRYPT_OK) { goto error; } | |
381 | y += x; | |
382 | ||
383 | x = (unsigned long)mp_unsigned_bin_size(b); | |
384 | STORE32L(x, out+y); y += 4; | |
385 | if ((err = mp_to_unsigned_bin(b, out+y)) != CRYPT_OK) { goto error; } | |
386 | y += x; | |
387 | ||
388 | /* check if size too big */ | |
389 | if (*outlen < y) { | |
390 | err = CRYPT_BUFFER_OVERFLOW; | |
391 | goto LBL_ERR; | |
392 | } | |
393 | ||
394 | /* store header */ | |
395 | packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED); | |
396 | *outlen = y; | |
397 | ||
398 | err = CRYPT_OK; | |
399 | goto LBL_ERR; | |
400 | error: | |
401 | LBL_ERR: | |
402 | mp_clear_multi(tmp, p1, g, p, m, k, b, a, NULL); | |
403 | ||
404 | XFREE(buf); | |
405 | ||
406 | return err; | |
407 | } | |
408 | ||
409 | ||
410 | /** | |
411 | Verify the signature given | |
412 | @param sig The signature | |
413 | @param siglen The length of the signature (octets) | |
414 | @param hash The hash that was signed | |
415 | @param hashlen The length of the hash (octets) | |
416 | @param stat [out] Result of signature comparison, 1==valid, 0==invalid | |
417 | @param key The public DH key that signed the hash | |
418 | @return CRYPT_OK if succsessful (even if signature is invalid) | |
419 | */ | |
420 | int dh_verify_hash(const unsigned char *sig, unsigned long siglen, | |
421 | const unsigned char *hash, unsigned long hashlen, | |
422 | int *stat, dh_key *key) | |
423 | { | |
424 | void *a, *b, *p, *g, *m, *tmp; | |
425 | unsigned long x, y; | |
426 | int err; | |
427 | ||
428 | LTC_ARGCHK(sig != NULL); | |
429 | LTC_ARGCHK(hash != NULL); | |
430 | LTC_ARGCHK(stat != NULL); | |
431 | LTC_ARGCHK(key != NULL); | |
432 | ||
433 | /* default to invalid */ | |
434 | *stat = 0; | |
435 | ||
436 | /* check initial input length */ | |
437 | if (siglen < PACKET_SIZE+4+4) { | |
438 | return CRYPT_INVALID_PACKET; | |
439 | } | |
440 | ||
441 | /* header ok? */ | |
442 | if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) { | |
443 | return err; | |
444 | } | |
445 | ||
446 | /* get hash out of packet */ | |
447 | y = PACKET_SIZE; | |
448 | ||
449 | /* init all bignums */ | |
450 | if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != CRYPT_OK) { | |
451 | return err; | |
452 | } | |
453 | ||
454 | /* load a and b */ | |
455 | INPUT_BIGNUM(a, sig, x, y, siglen); | |
456 | INPUT_BIGNUM(b, sig, x, y, siglen); | |
457 | ||
458 | /* load p and g */ | |
459 | if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error1; } | |
460 | if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error1; } | |
461 | ||
462 | /* load m */ | |
463 | if ((err = mp_read_unsigned_bin(m, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error1; } | |
464 | ||
465 | /* find g^m mod p */ | |
466 | if ((err = mp_exptmod(g, m, p, m)) != CRYPT_OK) { goto error1; } /* m = g^m mod p */ | |
467 | ||
468 | /* find y^a * a^b */ | |
469 | if ((err = mp_exptmod(key->y, a, p, tmp)) != CRYPT_OK) { goto error1; } /* tmp = y^a mod p */ | |
470 | if ((err = mp_exptmod(a, b, p, a)) != CRYPT_OK) { goto error1; } /* a = a^b mod p */ | |
471 | if ((err = mp_mulmod(a, tmp, p, a)) != CRYPT_OK) { goto error1; } /* a = y^a * a^b mod p */ | |
472 | ||
473 | /* y^a * a^b == g^m ??? */ | |
474 | if (mp_cmp(a, m) == 0) { | |
475 | *stat = 1; | |
476 | } | |
477 | ||
478 | /* clean up */ | |
479 | err = CRYPT_OK; | |
480 | goto done; | |
481 | error1: | |
482 | error: | |
483 | done: | |
484 | mp_clear_multi(tmp, m, g, p, b, a, NULL); | |
485 | return err; | |
486 | } |
114 | 114 | if ((sbuf = XMALLOC(seedbytes)) == NULL) { err = CRYPT_MEM; goto cleanup2; } |
115 | 115 | |
116 | 116 | err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, NULL); |
117 | if (err != CRYPT_OK) { goto cleanup1; }; | |
117 | if (err != CRYPT_OK) { goto cleanup1; } | |
118 | 118 | |
119 | 119 | if ((err = mp_2expt(t2L1, L-1)) != CRYPT_OK) { goto cleanup; } |
120 | 120 | /* t2L1 = 2^(L-1) */ |
195 | 195 | cleanup: |
196 | 196 | mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, NULL); |
197 | 197 | cleanup1: |
198 | XFREE(wbuf); | |
198 | XFREE(sbuf); | |
199 | 199 | cleanup2: |
200 | 200 | XFREE(wbuf); |
201 | 201 | cleanup3: |
19 | 19 | ECC Crypto, Tom St Denis |
20 | 20 | */ |
21 | 21 | |
22 | #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) | |
22 | #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_DESC)) | |
23 | 23 | |
24 | 24 | /** |
25 | 25 | Add two ECC points |
37 | 37 | ECC Crypto, Tom St Denis |
38 | 38 | */ |
39 | 39 | |
40 | #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) | |
40 | #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_DESC)) | |
41 | 41 | |
42 | 42 | /** |
43 | 43 | Double an ECC point |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_1_i2osp.c |
14 | Integer to Octet I2OSP, Tom St Denis | |
14 | Integer to Octet I2OSP, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
21 | 21 | */ |
22 | 22 | |
23 | 23 | /** |
24 | LTC_PKCS #1 Integer to binary | |
24 | PKCS #1 Integer to binary | |
25 | 25 | @param n The integer to store |
26 | 26 | @param modulus_len The length of the RSA modulus |
27 | 27 | @param out [out] The destination for the integer |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_1_mgf1.c |
14 | The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis | |
14 | The Mask Generation Function (MGF1) for PKCS #1, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
18 | 18 | |
19 | 19 | /** |
20 | Perform LTC_PKCS #1 MGF1 (internal) | |
20 | Perform PKCS #1 MGF1 (internal) | |
21 | 21 | @param seed The seed for MGF1 |
22 | 22 | @param seedlen The length of the seed |
23 | 23 | @param hash_idx The index of the hash desired |
34 | 34 | int err; |
35 | 35 | hash_state *md; |
36 | 36 | unsigned char *buf; |
37 | ||
37 | ||
38 | 38 | LTC_ARGCHK(seed != NULL); |
39 | 39 | LTC_ARGCHK(mask != NULL); |
40 | 40 | |
41 | 41 | /* ensure valid hash */ |
42 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
42 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
43 | 43 | return err; |
44 | 44 | } |
45 | 45 |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_1_oaep_decode.c |
14 | OAEP Padding for LTC_PKCS #1, Tom St Denis | |
14 | OAEP Padding for PKCS #1, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
18 | 18 | |
19 | 19 | /** |
20 | LTC_PKCS #1 v2.00 OAEP decode | |
20 | PKCS #1 v2.00 OAEP decode | |
21 | 21 | @param msg The encoded data to decode |
22 | 22 | @param msglen The length of the encoded data (octets) |
23 | 23 | @param lparam The session or system data (can be NULL) |
46 | 46 | |
47 | 47 | /* default to invalid packet */ |
48 | 48 | *res = 0; |
49 | ||
49 | ||
50 | 50 | /* test valid hash */ |
51 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
51 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
52 | 52 | return err; |
53 | 53 | } |
54 | 54 | hLen = hash_descriptor[hash_idx].hashsize; |
77 | 77 | } |
78 | 78 | |
79 | 79 | /* ok so it's now in the form |
80 | ||
81 | 0x00 || maskedseed || maskedDB | |
82 | ||
80 | ||
81 | 0x00 || maskedseed || maskedDB | |
82 | ||
83 | 83 | 1 || hLen || modulus_len - hLen - 1 |
84 | ||
84 | ||
85 | 85 | */ |
86 | 86 | |
87 | 87 | /* must have leading 0x00 byte */ |
99 | 99 | XMEMCPY(DB, msg + x, modulus_len - hLen - 1); |
100 | 100 | x += modulus_len - hLen - 1; |
101 | 101 | |
102 | /* compute MGF1 of maskedDB (hLen) */ | |
102 | /* compute MGF1 of maskedDB (hLen) */ | |
103 | 103 | if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { |
104 | 104 | goto LBL_ERR; |
105 | 105 | } |
116 | 116 | |
117 | 117 | /* xor against DB */ |
118 | 118 | for (y = 0; y < (modulus_len - hLen - 1); y++) { |
119 | DB[y] ^= mask[y]; | |
119 | DB[y] ^= mask[y]; | |
120 | 120 | } |
121 | 121 | |
122 | 122 | /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file pkcs_1_oaep_encode.c |
14 | OAEP Padding for LTC_PKCS #1, Tom St Denis | |
14 | OAEP Padding for PKCS #1, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
18 | 18 | |
19 | 19 | /** |
20 | LTC_PKCS #1 v2.00 OAEP encode | |
20 | PKCS #1 v2.00 OAEP encode | |
21 | 21 | @param msg The data to encode |
22 | 22 | @param msglen The length of the data to encode (octets) |
23 | 23 | @param lparam A session or system parameter (can be NULL) |
45 | 45 | LTC_ARGCHK(outlen != NULL); |
46 | 46 | |
47 | 47 | /* test valid hash */ |
48 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
48 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
49 | 49 | return err; |
50 | 50 | } |
51 | 51 | |
119 | 119 | |
120 | 120 | /* xor against DB */ |
121 | 121 | for (y = 0; y < (modulus_len - hLen - 1); y++) { |
122 | DB[y] ^= mask[y]; | |
122 | DB[y] ^= mask[y]; | |
123 | 123 | } |
124 | 124 | |
125 | /* compute MGF1 of maskedDB (hLen) */ | |
125 | /* compute MGF1 of maskedDB (hLen) */ | |
126 | 126 | if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { |
127 | 127 | goto LBL_ERR; |
128 | 128 | } |
148 | 148 | x += modulus_len - hLen - 1; |
149 | 149 | |
150 | 150 | *outlen = x; |
151 | ||
151 | ||
152 | 152 | err = CRYPT_OK; |
153 | 153 | LBL_ERR: |
154 | 154 | #ifdef LTC_CLEAN_STACK |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_1_pss_decode.c |
14 | LTC_PKCS #1 PSS Signature Padding, Tom St Denis | |
14 | PKCS #1 PSS Signature Padding, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
18 | 18 | |
19 | 19 | /** |
20 | LTC_PKCS #1 v2.00 PSS decode | |
20 | PKCS #1 v2.00 PSS decode | |
21 | 21 | @param msghash The hash to verify |
22 | 22 | @param msghashlen The length of the hash (octets) |
23 | 23 | @param sig The signature data (encoded data) |
53 | 53 | modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); |
54 | 54 | |
55 | 55 | /* check sizes */ |
56 | if ((saltlen > modulus_len) || | |
56 | if ((saltlen > modulus_len) || | |
57 | 57 | (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { |
58 | 58 | return CRYPT_PK_INVALID_SIZE; |
59 | 59 | } |
109 | 109 | for (y = 0; y < (modulus_len - hLen - 1); y++) { |
110 | 110 | DB[y] ^= mask[y]; |
111 | 111 | } |
112 | ||
112 | ||
113 | 113 | /* now clear the first byte [make sure smaller than modulus] */ |
114 | 114 | DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); |
115 | 115 | |
155 | 155 | err = CRYPT_OK; |
156 | 156 | LBL_ERR: |
157 | 157 | #ifdef LTC_CLEAN_STACK |
158 | zeromem(DB, modulus_len); | |
159 | zeromem(mask, modulus_len); | |
160 | zeromem(salt, modulus_len); | |
161 | zeromem(hash, modulus_len); | |
158 | zeromem(DB, modulus_len); | |
159 | zeromem(mask, modulus_len); | |
160 | zeromem(salt, modulus_len); | |
161 | zeromem(hash, modulus_len); | |
162 | 162 | #endif |
163 | 163 | |
164 | 164 | XFREE(hash); |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_1_pss_encode.c |
14 | LTC_PKCS #1 PSS Signature Padding, Tom St Denis | |
14 | PKCS #1 PSS Signature Padding, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
18 | 18 | |
19 | 19 | /** |
20 | LTC_PKCS #1 v2.00 Signature Encoding | |
20 | PKCS #1 v2.00 Signature Encoding | |
21 | 21 | @param msghash The hash to encode |
22 | 22 | @param msghashlen The length of the hash (octets) |
23 | 23 | @param saltlen The length of the salt desired (octets) |
30 | 30 | @return CRYPT_OK if successful |
31 | 31 | */ |
32 | 32 | int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, |
33 | unsigned long saltlen, prng_state *prng, | |
33 | unsigned long saltlen, prng_state *prng, | |
34 | 34 | int prng_idx, int hash_idx, |
35 | 35 | unsigned long modulus_bitlen, |
36 | 36 | unsigned char *out, unsigned long *outlen) |
153 | 153 | err = CRYPT_OK; |
154 | 154 | LBL_ERR: |
155 | 155 | #ifdef LTC_CLEAN_STACK |
156 | zeromem(DB, modulus_len); | |
157 | zeromem(mask, modulus_len); | |
158 | zeromem(salt, modulus_len); | |
159 | zeromem(hash, modulus_len); | |
156 | zeromem(DB, modulus_len); | |
157 | zeromem(mask, modulus_len); | |
158 | zeromem(salt, modulus_len); | |
159 | zeromem(hash, modulus_len); | |
160 | 160 | #endif |
161 | 161 | |
162 | 162 | XFREE(hash); |
11 | 11 | |
12 | 12 | /** @file pkcs_1_v1_5_decode.c |
13 | 13 | * |
14 | * LTC_PKCS #1 v1.5 Padding. (Andreas Lange) | |
14 | * PKCS #1 v1.5 Padding. (Andreas Lange) | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
18 | 18 | |
19 | /** @brief LTC_PKCS #1 v1.5 decode. | |
19 | /** @brief PKCS #1 v1.5 decode. | |
20 | 20 | * |
21 | 21 | * @param msg The encoded data to decode |
22 | 22 | * @param msglen The length of the encoded data (octets) |
28 | 28 | * |
29 | 29 | * @return CRYPT_OK if successful (even if invalid) |
30 | 30 | */ |
31 | int pkcs_1_v1_5_decode(const unsigned char *msg, | |
31 | int pkcs_1_v1_5_decode(const unsigned char *msg, | |
32 | 32 | unsigned long msglen, |
33 | 33 | int block_type, |
34 | 34 | unsigned long modulus_bitlen, |
35 | unsigned char *out, | |
35 | unsigned char *out, | |
36 | 36 | unsigned long *outlen, |
37 | 37 | int *is_valid) |
38 | 38 | { |
11 | 11 | |
12 | 12 | /*! \file pkcs_1_v1_5_encode.c |
13 | 13 | * |
14 | * LTC_PKCS #1 v1.5 Padding (Andreas Lange) | |
14 | * PKCS #1 v1.5 Padding (Andreas Lange) | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PKCS_1 |
18 | 18 | |
19 | /*! \brief LTC_PKCS #1 v1.5 encode. | |
19 | /*! \brief PKCS #1 v1.5 encode. | |
20 | 20 | * |
21 | 21 | * \param msg The data to encode |
22 | 22 | * \param msglen The length of the data to encode (octets) |
29 | 29 | * |
30 | 30 | * \return CRYPT_OK if successful |
31 | 31 | */ |
32 | int pkcs_1_v1_5_encode(const unsigned char *msg, | |
32 | int pkcs_1_v1_5_encode(const unsigned char *msg, | |
33 | 33 | unsigned long msglen, |
34 | 34 | int block_type, |
35 | 35 | unsigned long modulus_bitlen, |
36 | prng_state *prng, | |
36 | prng_state *prng, | |
37 | 37 | int prng_idx, |
38 | unsigned char *out, | |
38 | unsigned char *out, | |
39 | 39 | unsigned long *outlen) |
40 | 40 | { |
41 | 41 | unsigned long modulus_len, ps_len, i; |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file rsa_decrypt_key.c |
14 | RSA LTC_PKCS #1 Decryption, Tom St Denis and Andreas Lange | |
14 | RSA PKCS #1 Decryption, Tom St Denis and Andreas Lange | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_MRSA |
18 | 18 | |
19 | 19 | /** |
20 | LTC_PKCS #1 decrypt then v1.5 or OAEP depad | |
20 | PKCS #1 decrypt then v1.5 or OAEP depad | |
21 | 21 | @param in The ciphertext |
22 | 22 | @param inlen The length of the ciphertext (octets) |
23 | 23 | @param out [out] The plaintext |
89 | 89 | err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, |
90 | 90 | out, outlen, stat); |
91 | 91 | } else { |
92 | /* now LTC_PKCS #1 v1.5 depad the packet */ | |
92 | /* now PKCS #1 v1.5 depad the packet */ | |
93 | 93 | err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); |
94 | 94 | } |
95 | 95 |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file rsa_encrypt_key.c |
14 | RSA LTC_PKCS #1 encryption, Tom St Denis and Andreas Lange | |
14 | RSA PKCS #1 encryption, Tom St Denis and Andreas Lange | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_MRSA |
18 | 18 | |
19 | 19 | /** |
20 | (LTC_PKCS #1 v2.0) OAEP pad then encrypt | |
20 | (PKCS #1 v2.0) OAEP pad then encrypt | |
21 | 21 | @param in The plaintext |
22 | 22 | @param inlen The length of the plaintext (octets) |
23 | 23 | @param out [out] The ciphertext |
81 | 81 | return err; |
82 | 82 | } |
83 | 83 | } else { |
84 | /* LTC_PKCS #1 v1.5 pad the key */ | |
84 | /* PKCS #1 v1.5 pad the key */ | |
85 | 85 | x = *outlen; |
86 | 86 | if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME, |
87 | 87 | modulus_bitlen, prng, prng_idx, |
90 | 90 | } |
91 | 91 | } |
92 | 92 | |
93 | /* rsa exptmod the OAEP or LTC_PKCS #1 v1.5 pad */ | |
93 | /* rsa exptmod the OAEP or PKCS #1 v1.5 pad */ | |
94 | 94 | return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key); |
95 | 95 | } |
96 | 96 |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file rsa_export.c |
14 | Export RSA LTC_PKCS keys, Tom St Denis | |
15 | */ | |
14 | Export RSA PKCS keys, Tom St Denis | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_MRSA |
18 | 18 | |
19 | 19 | /** |
20 | This will export either an RSAPublicKey or RSAPrivateKey [defined in LTC_PKCS #1 v2.1] | |
20 | This will export either an RSAPublicKey or RSAPrivateKey [defined in PKCS #1 v2.1] | |
21 | 21 | @param out [out] Destination of the packet |
22 | 22 | @param outlen [in/out] The max size and resulting size of the packet |
23 | 23 | @param type The type of exported key (PK_PRIVATE or PK_PUBLIC) |
24 | 24 | @param key The RSA key to export |
25 | 25 | @return CRYPT_OK if successful |
26 | */ | |
26 | */ | |
27 | 27 | int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) |
28 | 28 | { |
29 | 29 | unsigned long zero=0; |
39 | 39 | |
40 | 40 | if (type == PK_PRIVATE) { |
41 | 41 | /* private key */ |
42 | /* output is | |
42 | /* output is | |
43 | 43 | Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p |
44 | 44 | */ |
45 | return der_encode_sequence_multi(out, outlen, | |
46 | LTC_ASN1_SHORT_INTEGER, 1UL, &zero, | |
47 | LTC_ASN1_INTEGER, 1UL, key->N, | |
45 | return der_encode_sequence_multi(out, outlen, | |
46 | LTC_ASN1_SHORT_INTEGER, 1UL, &zero, | |
47 | LTC_ASN1_INTEGER, 1UL, key->N, | |
48 | 48 | LTC_ASN1_INTEGER, 1UL, key->e, |
49 | LTC_ASN1_INTEGER, 1UL, key->d, | |
50 | LTC_ASN1_INTEGER, 1UL, key->p, | |
51 | LTC_ASN1_INTEGER, 1UL, key->q, | |
49 | LTC_ASN1_INTEGER, 1UL, key->d, | |
50 | LTC_ASN1_INTEGER, 1UL, key->p, | |
51 | LTC_ASN1_INTEGER, 1UL, key->q, | |
52 | 52 | LTC_ASN1_INTEGER, 1UL, key->dP, |
53 | LTC_ASN1_INTEGER, 1UL, key->dQ, | |
54 | LTC_ASN1_INTEGER, 1UL, key->qP, | |
53 | LTC_ASN1_INTEGER, 1UL, key->dQ, | |
54 | LTC_ASN1_INTEGER, 1UL, key->qP, | |
55 | 55 | LTC_ASN1_EOL, 0UL, NULL); |
56 | 56 | } else { |
57 | 57 | /* public key */ |
13 | 13 | |
14 | 14 | /** |
15 | 15 | @file rsa_exptmod.c |
16 | RSA LTC_PKCS exptmod, Tom St Denis | |
16 | RSA PKCS exptmod, Tom St Denis | |
17 | 17 | */ |
18 | 18 | |
19 | 19 | #ifdef LTC_MRSA |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file rsa_get_size.c | |
14 | Retrieve the size of an RSA key, Steffen Jaeckel. | |
15 | */ | |
16 | ||
17 | #ifdef LTC_MRSA | |
18 | ||
19 | /** | |
20 | Retrieve the size in bytes of an RSA key. | |
21 | @param key The RSA key | |
22 | @return The size in bytes of the RSA key or INT_MAX on error. | |
23 | */ | |
24 | int rsa_get_size(rsa_key *key) | |
25 | { | |
26 | int ret = INT_MAX; | |
27 | LTC_ARGCHKVD(key != NULL); | |
28 | ||
29 | if (key) | |
30 | { | |
31 | ret = mp_unsigned_bin_size(key->N); | |
32 | } /* if */ | |
33 | ||
34 | return ret; | |
35 | } | |
36 | ||
37 | #endif | |
38 | ||
39 | /* $Source$ */ | |
40 | /* $Revision$ */ | |
41 | /* $Date$ */ |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file rsa_import.c |
14 | Import a LTC_PKCS RSA key, Tom St Denis | |
15 | */ | |
14 | Import a PKCS RSA key, Tom St Denis | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_MRSA |
18 | 18 | |
19 | 19 | /** |
20 | Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1] | |
20 | Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1] | |
21 | 21 | @param in The packet to import from |
22 | 22 | @param inlen It's length (octets) |
23 | 23 | @param key [out] Destination for newly imported key |
35 | 35 | LTC_ARGCHK(ltc_mp.name != NULL); |
36 | 36 | |
37 | 37 | /* init key */ |
38 | if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, | |
38 | if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, | |
39 | 39 | &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { |
40 | 40 | return err; |
41 | 41 | } |
66 | 66 | goto LBL_FREE; |
67 | 67 | } |
68 | 68 | |
69 | /* not SSL public key, try to match against LTC_PKCS #1 standards */ | |
70 | if ((err = der_decode_sequence_multi(in, inlen, | |
71 | LTC_ASN1_INTEGER, 1UL, key->N, | |
69 | /* not SSL public key, try to match against PKCS #1 standards */ | |
70 | if ((err = der_decode_sequence_multi(in, inlen, | |
71 | LTC_ASN1_INTEGER, 1UL, key->N, | |
72 | 72 | LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { |
73 | 73 | goto LBL_ERR; |
74 | 74 | } |
75 | 75 | |
76 | 76 | if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { |
77 | if ((err = mp_init(&zero)) != CRYPT_OK) { | |
77 | if ((err = mp_init(&zero)) != CRYPT_OK) { | |
78 | 78 | goto LBL_ERR; |
79 | 79 | } |
80 | 80 | /* it's a private key */ |
81 | if ((err = der_decode_sequence_multi(in, inlen, | |
82 | LTC_ASN1_INTEGER, 1UL, zero, | |
83 | LTC_ASN1_INTEGER, 1UL, key->N, | |
81 | if ((err = der_decode_sequence_multi(in, inlen, | |
82 | LTC_ASN1_INTEGER, 1UL, zero, | |
83 | LTC_ASN1_INTEGER, 1UL, key->N, | |
84 | 84 | LTC_ASN1_INTEGER, 1UL, key->e, |
85 | LTC_ASN1_INTEGER, 1UL, key->d, | |
86 | LTC_ASN1_INTEGER, 1UL, key->p, | |
87 | LTC_ASN1_INTEGER, 1UL, key->q, | |
85 | LTC_ASN1_INTEGER, 1UL, key->d, | |
86 | LTC_ASN1_INTEGER, 1UL, key->p, | |
87 | LTC_ASN1_INTEGER, 1UL, key->q, | |
88 | 88 | LTC_ASN1_INTEGER, 1UL, key->dP, |
89 | LTC_ASN1_INTEGER, 1UL, key->dQ, | |
90 | LTC_ASN1_INTEGER, 1UL, key->qP, | |
89 | LTC_ASN1_INTEGER, 1UL, key->dQ, | |
90 | LTC_ASN1_INTEGER, 1UL, key->qP, | |
91 | 91 | LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { |
92 | 92 | mp_clear(zero); |
93 | 93 | goto LBL_ERR; |
100 | 100 | goto LBL_ERR; |
101 | 101 | } else { |
102 | 102 | /* it's a public key and we lack e */ |
103 | if ((err = der_decode_sequence_multi(in, inlen, | |
104 | LTC_ASN1_INTEGER, 1UL, key->N, | |
105 | LTC_ASN1_INTEGER, 1UL, key->e, | |
103 | if ((err = der_decode_sequence_multi(in, inlen, | |
104 | LTC_ASN1_INTEGER, 1UL, key->N, | |
105 | LTC_ASN1_INTEGER, 1UL, key->e, | |
106 | 106 | LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { |
107 | 107 | goto LBL_ERR; |
108 | 108 | } |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file rsa_sign_hash.c |
14 | RSA LTC_PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange | |
14 | RSA PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_MRSA |
18 | 18 | |
19 | 19 | /** |
20 | LTC_PKCS #1 pad then sign | |
20 | PKCS #1 pad then sign | |
21 | 21 | @param in The hash to sign |
22 | 22 | @param inlen The length of the hash to sign (octets) |
23 | 23 | @param out [out] The signature |
78 | 78 | return err; |
79 | 79 | } |
80 | 80 | } else { |
81 | /* LTC_PKCS #1 v1.5 pad the hash */ | |
81 | /* PKCS #1 v1.5 pad the hash */ | |
82 | 82 | unsigned char *tmpin; |
83 | 83 | ltc_asn1_list digestinfo[2], siginfo[2]; |
84 | 84 |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | * | |
8 | * http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file rsa_sign_saltlen_get_ex.c | |
14 | Retrieve the maximum size of the salt, Steffen Jaeckel. | |
15 | */ | |
16 | ||
17 | #ifdef LTC_MRSA | |
18 | ||
19 | /** | |
20 | Retrieve the maximum possible size of the salt when creating a PKCS#1 PSS signature. | |
21 | @param padding Type of padding (LTC_PKCS_1_PSS only) | |
22 | @param hash_idx The index of the desired hash | |
23 | @param key The RSA key | |
24 | @return The maximum salt length in bytes or INT_MAX on error. | |
25 | */ | |
26 | int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, rsa_key *key) | |
27 | { | |
28 | int ret = INT_MAX; | |
29 | LTC_ARGCHKVD(key != NULL); | |
30 | ||
31 | if ((hash_is_valid(hash_idx) == CRYPT_OK) && | |
32 | (padding == LTC_PKCS_1_PSS)) | |
33 | { | |
34 | ret = rsa_get_size(key); | |
35 | if (ret < INT_MAX) | |
36 | { | |
37 | ret -= (hash_descriptor[hash_idx].hashsize + 2); | |
38 | } /* if */ | |
39 | } /* if */ | |
40 | ||
41 | return ret; | |
42 | } | |
43 | ||
44 | #endif | |
45 | ||
46 | /* $Source$ */ | |
47 | /* $Revision$ */ | |
48 | /* $Date$ */ |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file rsa_verify_hash.c |
14 | RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange | |
14 | RSA PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_MRSA |
18 | 18 | |
19 | 19 | /** |
20 | LTC_PKCS #1 de-sign then v1.5 or PSS depad | |
20 | PKCS #1 de-sign then v1.5 or PSS depad | |
21 | 21 | @param sig The signature data |
22 | 22 | @param siglen The length of the signature data (octets) |
23 | 23 | @param hash The hash of the message that was signed |
93 | 93 | /* PSS decode and verify it */ |
94 | 94 | err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); |
95 | 95 | } else { |
96 | /* LTC_PKCS #1 v1.5 decode it */ | |
96 | /* PKCS #1 v1.5 decode it */ | |
97 | 97 | unsigned char *out; |
98 | 98 | unsigned long outlen, loid[16]; |
99 | 99 | int decoded; |
114 | 114 | } |
115 | 115 | |
116 | 116 | if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { |
117 | XFREE(out); | |
117 | XFREE(out); | |
118 | 118 | goto bail_2; |
119 | 119 | } |
120 | 120 |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file rng_get_bytes.c |
14 | 14 | portable way to get secure random bits to feed a PRNG (Tom St Denis) |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_DEVRANDOM |
18 | 18 | /* on *NIX read /dev/random */ |
19 | static unsigned long rng_nix(unsigned char *buf, unsigned long len, | |
19 | static unsigned long rng_nix(unsigned char *buf, unsigned long len, | |
20 | 20 | void (*callback)(void)) |
21 | 21 | { |
22 | 22 | #ifdef LTC_NO_FILE |
33 | 33 | if (f == NULL) { |
34 | 34 | return 0; |
35 | 35 | } |
36 | ||
36 | ||
37 | 37 | /* disable buffering */ |
38 | 38 | if (setvbuf(f, NULL, _IONBF, 0) != 0) { |
39 | 39 | fclose(f); |
40 | 40 | return 0; |
41 | } | |
42 | ||
41 | } | |
42 | ||
43 | 43 | x = (unsigned long)fread(buf, 1, (size_t)len, f); |
44 | 44 | fclose(f); |
45 | 45 | return x; |
53 | 53 | |
54 | 54 | #define ANSI_RNG |
55 | 55 | |
56 | static unsigned long rng_ansic(unsigned char *buf, unsigned long len, | |
56 | static unsigned long rng_ansic(unsigned char *buf, unsigned long len, | |
57 | 57 | void (*callback)(void)) |
58 | 58 | { |
59 | 59 | clock_t t1; |
75 | 75 | } while (a == b); |
76 | 76 | acc = (acc << 1) | a; |
77 | 77 | } |
78 | *buf++ = acc; | |
78 | *buf++ = acc; | |
79 | 79 | acc = 0; |
80 | 80 | bits = 8; |
81 | 81 | } |
83 | 83 | return l; |
84 | 84 | } |
85 | 85 | |
86 | #endif | |
86 | #endif | |
87 | 87 | |
88 | 88 | /* Try the Microsoft CSP */ |
89 | #if defined(WIN32) || defined(WINCE) | |
90 | #ifndef _WIN32_WINNT | |
91 | #define _WIN32_WINNT 0x0400 | |
92 | #endif | |
89 | #if defined(WIN32) || defined(_WIN32) || defined(WINCE) | |
90 | #ifndef _WIN32_WINNT | |
91 | #define _WIN32_WINNT 0x0400 | |
92 | #endif | |
93 | 93 | #ifdef WINCE |
94 | 94 | #define UNDER_CE |
95 | 95 | #define ARM |
99 | 99 | #include <windows.h> |
100 | 100 | #include <wincrypt.h> |
101 | 101 | |
102 | static unsigned long rng_win32(unsigned char *buf, unsigned long len, | |
102 | static unsigned long rng_win32(unsigned char *buf, unsigned long len, | |
103 | 103 | void (*callback)(void)) |
104 | 104 | { |
105 | 105 | HCRYPTPROV hProv = 0; |
106 | if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, | |
107 | (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && | |
108 | !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, | |
106 | if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, | |
107 | (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && | |
108 | !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, | |
109 | 109 | CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) |
110 | 110 | return 0; |
111 | 111 | |
126 | 126 | @param outlen Length desired (octets) |
127 | 127 | @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL |
128 | 128 | @return Number of octets read |
129 | */ | |
130 | unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, | |
129 | */ | |
130 | unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, | |
131 | 131 | void (*callback)(void)) |
132 | 132 | { |
133 | 133 | unsigned long x; |
137 | 137 | #if defined(LTC_DEVRANDOM) |
138 | 138 | x = rng_nix(out, outlen, callback); if (x != 0) { return x; } |
139 | 139 | #endif |
140 | #ifdef WIN32 | |
140 | #if defined(WIN32) || defined(_WIN32) || defined(WINCE) | |
141 | 141 | x = rng_win32(out, outlen, callback); if (x != 0) { return x; } |
142 | 142 | #endif |
143 | 143 | #ifdef ANSI_RNG |