ltc sync whitespaces
Karel Miko
7 years ago
674 | 674 | } |
675 | 675 | }; |
676 | 676 | |
677 | symmetric_key key; | |
678 | unsigned char tmp[2][16]; | |
679 | int i, y; | |
680 | ||
681 | for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { | |
677 | symmetric_key key; | |
678 | unsigned char tmp[2][16]; | |
679 | int i, y; | |
680 | ||
681 | for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { | |
682 | 682 | zeromem(&key, sizeof(key)); |
683 | 683 | if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { |
684 | 684 | return err; |
706 | 706 | return CRYPT_FAIL_TESTVECTOR; |
707 | 707 | } |
708 | 708 | |
709 | /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
710 | for (y = 0; y < 16; y++) tmp[0][y] = 0; | |
711 | for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); | |
712 | for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); | |
713 | for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
714 | } | |
715 | return CRYPT_OK; | |
709 | /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
710 | for (y = 0; y < 16; y++) tmp[0][y] = 0; | |
711 | for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); | |
712 | for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); | |
713 | for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
714 | } | |
715 | return CRYPT_OK; | |
716 | 716 | #endif |
717 | 717 | } |
718 | 718 |
925 | 925 | return CRYPT_INVALID_ROUNDS; |
926 | 926 | } |
927 | 927 | |
928 | /* | |
929 | * map cipher key to initial key state (mu): | |
930 | */ | |
931 | for (i = 0, pos = 0; i < N; i++, pos += 4) { | |
928 | /* | |
929 | * map cipher key to initial key state (mu): | |
930 | */ | |
931 | for (i = 0, pos = 0; i < N; i++, pos += 4) { | |
932 | 932 | kappa[i] = |
933 | 933 | (((ulong32)key[pos ]) << 24) ^ |
934 | 934 | (((ulong32)key[pos + 1]) << 16) ^ |
935 | 935 | (((ulong32)key[pos + 2]) << 8) ^ |
936 | 936 | (((ulong32)key[pos + 3]) ); |
937 | } | |
937 | } | |
938 | 938 | |
939 | 939 | /* |
940 | 940 | * generate R + 1 round keys: |
1982 | 1982 | return CRYPT_FAIL_TESTVECTOR; |
1983 | 1983 | } |
1984 | 1984 | |
1985 | /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
1986 | for (y = 0; y < 8; y++) tmp[y] = 0; | |
1987 | for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des); | |
1988 | for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des); | |
1989 | for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
1990 | } | |
1985 | /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
1986 | for (y = 0; y < 8; y++) tmp[y] = 0; | |
1987 | for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des); | |
1988 | for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des); | |
1989 | for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
1990 | } | |
1991 | 1991 | |
1992 | 1992 | return CRYPT_OK; |
1993 | 1993 | #endif |
200 | 200 | */ |
201 | 201 | int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) |
202 | 202 | { |
203 | int i; | |
204 | ulong32 tmp, k1, k2, k3, k4; | |
205 | ||
206 | if (keylen != 16) { | |
207 | return CRYPT_INVALID_KEYSIZE; | |
208 | } | |
209 | ||
210 | if (num_rounds != 16 && num_rounds != 0) { | |
211 | return CRYPT_INVALID_ROUNDS; | |
212 | } | |
213 | ||
214 | /* load key */ | |
215 | LOAD32H(k1, key); | |
216 | LOAD32H(k2, key+4); | |
217 | LOAD32H(k3, key+8); | |
218 | LOAD32H(k4, key+12); | |
219 | ||
220 | for (i = 0; i < 16; i++) { | |
221 | skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]); | |
222 | skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]); | |
223 | if (i&1) { | |
224 | tmp = k3; | |
225 | k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF; | |
226 | k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF; | |
227 | } else { | |
228 | tmp = k1; | |
229 | k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF; | |
230 | k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF; | |
203 | int i; | |
204 | ulong32 tmp, k1, k2, k3, k4; | |
205 | ||
206 | if (keylen != 16) { | |
207 | return CRYPT_INVALID_KEYSIZE; | |
208 | } | |
209 | ||
210 | if (num_rounds != 16 && num_rounds != 0) { | |
211 | return CRYPT_INVALID_ROUNDS; | |
212 | } | |
213 | ||
214 | /* load key */ | |
215 | LOAD32H(k1, key); | |
216 | LOAD32H(k2, key+4); | |
217 | LOAD32H(k3, key+8); | |
218 | LOAD32H(k4, key+12); | |
219 | ||
220 | for (i = 0; i < 16; i++) { | |
221 | skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]); | |
222 | skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]); | |
223 | if (i&1) { | |
224 | tmp = k3; | |
225 | k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF; | |
226 | k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF; | |
227 | } else { | |
228 | tmp = k1; | |
229 | k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF; | |
230 | k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF; | |
231 | 231 | } |
232 | 232 | /* reverse keys for decrypt */ |
233 | 233 | skey->kseed.dK[2*(15-i)+0] = skey->kseed.K[2*i+0]; |
234 | 234 | skey->kseed.dK[2*(15-i)+1] = skey->kseed.K[2*i+1]; |
235 | } | |
236 | ||
237 | return CRYPT_OK; | |
235 | } | |
236 | ||
237 | return CRYPT_OK; | |
238 | 238 | } |
239 | 239 | |
240 | 240 | static void rounds(ulong32 *P, ulong32 *K) |
302 | 302 | return CRYPT_FAIL_TESTVECTOR; |
303 | 303 | } |
304 | 304 | |
305 | /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
306 | for (y = 0; y < 16; y++) tmp[0][y] = 0; | |
307 | for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key); | |
308 | for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key); | |
309 | for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
305 | /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
306 | for (y = 0; y < 16; y++) tmp[0][y] = 0; | |
307 | for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key); | |
308 | for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key); | |
309 | for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
310 | 310 | } |
311 | 311 | return CRYPT_OK; |
312 | 312 | #endif |
41 | 41 | /* form B_0 == flags | Nonce N | l(m) */ |
42 | 42 | x = 0; |
43 | 43 | ccm->PAD[x++] = (unsigned char)(((ccm->aadlen > 0) ? (1<<6) : 0) | |
44 | (((ccm->taglen - 2)>>1)<<3) | | |
45 | (ccm->L-1)); | |
44 | (((ccm->taglen - 2)>>1)<<3) | | |
45 | (ccm->L-1)); | |
46 | 46 | |
47 | 47 | /* nonce */ |
48 | 48 | for (y = 0; y < (16 - (ccm->L + 1)); y++) { |
7 | 7 | * |
8 | 8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
9 | 9 | */ |
10 | /** | |
10 | /** | |
11 | 11 | @file eax_addheader.c |
12 | EAX implementation, add meta-data, by Tom St Denis | |
12 | EAX implementation, add meta-data, by Tom St Denis | |
13 | 13 | */ |
14 | 14 | #include "tomcrypt.h" |
15 | 15 | |
16 | 16 | #ifdef LTC_EAX_MODE |
17 | 17 | |
18 | /** | |
19 | add header (metadata) to the stream | |
18 | /** | |
19 | add header (metadata) to the stream | |
20 | 20 | @param eax The current EAX state |
21 | 21 | @param header The header (meta-data) data you wish to add to the state |
22 | 22 | @param length The length of the header data |
23 | 23 | @return CRYPT_OK if successful |
24 | 24 | */ |
25 | int eax_addheader(eax_state *eax, const unsigned char *header, | |
25 | int eax_addheader(eax_state *eax, const unsigned char *header, | |
26 | 26 | unsigned long length) |
27 | 27 | { |
28 | 28 | LTC_ARGCHK(eax != NULL); |
8 | 8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
9 | 9 | */ |
10 | 10 | |
11 | /** | |
11 | /** | |
12 | 12 | @file eax_decrypt.c |
13 | 13 | EAX implementation, decrypt block, by Tom St Denis |
14 | 14 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_EAX_MODE |
18 | 18 | |
19 | /** | |
19 | /** | |
20 | 20 | Decrypt data with the EAX protocol |
21 | 21 | @param eax The EAX state |
22 | 22 | @param ct The ciphertext |
24 | 24 | @param length The length (octets) of the ciphertext |
25 | 25 | @return CRYPT_OK if successful |
26 | 26 | */ |
27 | int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, | |
27 | int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, | |
28 | 28 | unsigned long length) |
29 | 29 | { |
30 | 30 | int err; |
31 | ||
31 | ||
32 | 32 | LTC_ARGCHK(eax != NULL); |
33 | 33 | LTC_ARGCHK(pt != NULL); |
34 | 34 | LTC_ARGCHK(ct != NULL); |
76 | 76 | if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) { |
77 | 77 | goto LBL_ERR; |
78 | 78 | } |
79 | ||
79 | ||
80 | 80 | buflen = taglen; |
81 | 81 | if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) { |
82 | 82 | goto LBL_ERR; |
86 | 86 | if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) { |
87 | 87 | *stat = 1; |
88 | 88 | } |
89 | ||
89 | ||
90 | 90 | err = CRYPT_OK; |
91 | 91 | LBL_ERR: |
92 | 92 | #ifdef LTC_CLEAN_STACK |
50 | 50 | /* finish ctomac */ |
51 | 51 | len = MAXBLOCKSIZE; |
52 | 52 | if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) { |
53 | goto LBL_ERR; | |
53 | goto LBL_ERR; | |
54 | 54 | } |
55 | 55 | |
56 | 56 | /* finish headeromac */ |
58 | 58 | /* note we specifically don't reset len so the two lens are minimal */ |
59 | 59 | |
60 | 60 | if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) { |
61 | goto LBL_ERR; | |
61 | goto LBL_ERR; | |
62 | 62 | } |
63 | 63 | |
64 | 64 | /* terminate the CTR chain */ |
10 | 10 | |
11 | 11 | /** |
12 | 12 | @file eax_encrypt.c |
13 | EAX implementation, encrypt block by Tom St Denis | |
13 | EAX implementation, encrypt block by Tom St Denis | |
14 | 14 | */ |
15 | 15 | #include "tomcrypt.h" |
16 | 16 | |
24 | 24 | @param length The length of the plaintext (octets) |
25 | 25 | @return CRYPT_OK if successful |
26 | 26 | */ |
27 | int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, | |
27 | int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, | |
28 | 28 | unsigned long length) |
29 | 29 | { |
30 | 30 | int err; |
31 | ||
31 | ||
32 | 32 | LTC_ARGCHK(eax != NULL); |
33 | 33 | LTC_ARGCHK(pt != NULL); |
34 | 34 | LTC_ARGCHK(ct != NULL); |
52 | 52 | eax = XMALLOC(sizeof(*eax)); |
53 | 53 | |
54 | 54 | if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { |
55 | goto LBL_ERR; | |
55 | goto LBL_ERR; | |
56 | 56 | } |
57 | 57 | |
58 | 58 | if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) { |
59 | goto LBL_ERR; | |
59 | goto LBL_ERR; | |
60 | 60 | } |
61 | ||
61 | ||
62 | 62 | if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) { |
63 | goto LBL_ERR; | |
63 | goto LBL_ERR; | |
64 | 64 | } |
65 | 65 | |
66 | 66 | err = CRYPT_OK; |
71 | 71 | |
72 | 72 | XFREE(eax); |
73 | 73 | |
74 | return err; | |
74 | return err; | |
75 | 75 | } |
76 | 76 | |
77 | 77 | #endif |
8 | 8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
9 | 9 | */ |
10 | 10 | |
11 | /** | |
11 | /** | |
12 | 12 | @file eax_init.c |
13 | EAX implementation, initialized EAX state, by Tom St Denis | |
13 | EAX implementation, initialized EAX state, by Tom St Denis | |
14 | 14 | */ |
15 | 15 | #include "tomcrypt.h" |
16 | 16 | |
17 | 17 | #ifdef LTC_EAX_MODE |
18 | 18 | |
19 | /** | |
19 | /** | |
20 | 20 | Initialized an EAX state |
21 | 21 | @param eax [out] The EAX state to initialize |
22 | 22 | @param cipher The index of the desired cipher |
28 | 28 | @param headerlen The header length (octets) |
29 | 29 | @return CRYPT_OK if successful |
30 | 30 | */ |
31 | int eax_init(eax_state *eax, int cipher, | |
31 | int eax_init(eax_state *eax, int cipher, | |
32 | 32 | const unsigned char *key, unsigned long keylen, |
33 | 33 | const unsigned char *nonce, unsigned long noncelen, |
34 | 34 | const unsigned char *header, unsigned long headerlen) |
68 | 68 | /* N = LTC_OMAC_0K(nonce) */ |
69 | 69 | zeromem(buf, MAXBLOCKSIZE); |
70 | 70 | if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { |
71 | goto LBL_ERR; | |
71 | goto LBL_ERR; | |
72 | 72 | } |
73 | 73 | |
74 | 74 | /* omac the [0]_n */ |
75 | 75 | if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) { |
76 | goto LBL_ERR; | |
76 | goto LBL_ERR; | |
77 | 77 | } |
78 | 78 | /* omac the nonce */ |
79 | 79 | if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) { |
80 | goto LBL_ERR; | |
80 | goto LBL_ERR; | |
81 | 81 | } |
82 | 82 | /* store result */ |
83 | 83 | len = sizeof(eax->N); |
84 | 84 | if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) { |
85 | goto LBL_ERR; | |
85 | goto LBL_ERR; | |
86 | 86 | } |
87 | 87 | |
88 | 88 | /* H = LTC_OMAC_1K(header) */ |
90 | 90 | buf[blklen - 1] = 1; |
91 | 91 | |
92 | 92 | if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) { |
93 | goto LBL_ERR; | |
93 | goto LBL_ERR; | |
94 | 94 | } |
95 | 95 | |
96 | 96 | /* omac the [1]_n */ |
97 | 97 | if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) { |
98 | goto LBL_ERR; | |
98 | goto LBL_ERR; | |
99 | 99 | } |
100 | 100 | /* omac the header */ |
101 | 101 | if (headerlen != 0) { |
102 | 102 | if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) { |
103 | goto LBL_ERR; | |
103 | goto LBL_ERR; | |
104 | 104 | } |
105 | 105 | } |
106 | 106 | |
108 | 108 | |
109 | 109 | /* setup the CTR mode */ |
110 | 110 | if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) { |
111 | goto LBL_ERR; | |
111 | goto LBL_ERR; | |
112 | 112 | } |
113 | 113 | |
114 | 114 | /* setup the LTC_OMAC for the ciphertext */ |
115 | if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { | |
116 | goto LBL_ERR; | |
115 | if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { | |
116 | goto LBL_ERR; | |
117 | 117 | } |
118 | 118 | |
119 | 119 | /* omac [2]_n */ |
120 | 120 | zeromem(buf, MAXBLOCKSIZE); |
121 | 121 | buf[blklen-1] = 2; |
122 | 122 | if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) { |
123 | goto LBL_ERR; | |
123 | goto LBL_ERR; | |
124 | 124 | } |
125 | 125 | |
126 | 126 | err = CRYPT_OK; |
136 | 136 | return err; |
137 | 137 | } |
138 | 138 | |
139 | #endif | |
139 | #endif | |
140 | 140 | |
141 | 141 | /* $Source$ */ |
142 | 142 | /* $Revision$ */ |
23 | 23 | @param taglen [in/out] The length of the MAC tag |
24 | 24 | @return CRYPT_OK on success |
25 | 25 | */ |
26 | int gcm_done(gcm_state *gcm, | |
26 | int gcm_done(gcm_state *gcm, | |
27 | 27 | unsigned char *tag, unsigned long *taglen) |
28 | 28 | { |
29 | 29 | unsigned long x; |
16 | 16 | |
17 | 17 | #if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) |
18 | 18 | |
19 | /* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the | |
19 | /* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the | |
20 | 20 | * lower 16 bits are not zero'ed I removed the upper 14 bytes */ |
21 | 21 | const unsigned char gcm_shift_table[256*2] = { |
22 | 22 | 0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e, |
72 | 72 | static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; |
73 | 73 | static const unsigned char poly[] = { 0x00, 0xE1 }; |
74 | 74 | |
75 | ||
75 | ||
76 | 76 | /** |
77 | 77 | GCM GF multiplier (internal use only) bitserial |
78 | 78 | @param a First value |
79 | 79 | @param b Second value |
80 | 80 | @param c Destination for a * b |
81 | */ | |
81 | */ | |
82 | 82 | void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) |
83 | 83 | { |
84 | 84 | unsigned char Z[16], V[16]; |
89 | 89 | for (x = 0; x < 128; x++) { |
90 | 90 | if (b[x>>3] & mask[x&7]) { |
91 | 91 | for (y = 0; y < 16; y++) { |
92 | Z[y] ^= V[y]; | |
92 | Z[y] ^= V[y]; | |
93 | 93 | } |
94 | 94 | } |
95 | 95 | z = V[15] & 0x01; |
112 | 112 | @param a First value |
113 | 113 | @param b Second value |
114 | 114 | @param c Destination for a * b |
115 | */ | |
115 | */ | |
116 | 116 | void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) |
117 | 117 | { |
118 | 118 | int i, j, k, u; |
128 | 128 | LOAD32H(B[M(1)][i], a + (i<<2)); |
129 | 129 | LOAD32L(pB[i], b + (i<<2)); |
130 | 130 | } |
131 | #else | |
131 | #else | |
132 | 132 | for (i = 0; i < 2; i++) { |
133 | 133 | LOAD64H(B[M(1)][i], a + (i<<3)); |
134 | 134 | LOAD64L(pB[i], b + (i<<3)); |
153 | 153 | B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i]; |
154 | 154 | B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i]; |
155 | 155 | B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i]; |
156 | ||
156 | ||
157 | 157 | /* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */ |
158 | 158 | B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i]; |
159 | 159 | B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i]; |
192 | 192 | for (i = 0; i < 8; i++) { |
193 | 193 | STORE32H(tmp[i], pTmp + (i<<2)); |
194 | 194 | } |
195 | #else | |
195 | #else | |
196 | 196 | for (i = 0; i < 4; i++) { |
197 | 197 | STORE64H(tmp[i], pTmp + (i<<3)); |
198 | 198 | } |
217 | 217 | /* $Source$ */ |
218 | 218 | /* $Revision$ */ |
219 | 219 | /* $Date$ */ |
220 | ||
220 |
24 | 24 | @param keylen The length of the secret key |
25 | 25 | @return CRYPT_OK on success |
26 | 26 | */ |
27 | int gcm_init(gcm_state *gcm, int cipher, | |
27 | int gcm_init(gcm_state *gcm, int cipher, | |
28 | 28 | const unsigned char *key, int keylen) |
29 | 29 | { |
30 | 30 | int err; |
91 | 91 | } |
92 | 92 | gcm->PC[x][y][0] = gcm_shift_table[t<<1]; |
93 | 93 | gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1]; |
94 | } | |
95 | } | |
94 | } | |
95 | } | |
96 | 96 | |
97 | 97 | #endif |
98 | 98 |
21 | 21 | @param cipher Index of cipher to use |
22 | 22 | @param key The secret key |
23 | 23 | @param keylen The length of the secret key |
24 | @param IV The initial vector | |
24 | @param IV The initial vector | |
25 | 25 | @param IVlen The length of the initial vector |
26 | 26 | @param adata The additional authentication data (header) |
27 | 27 | @param adatalen The length of the adata |
38 | 38 | const unsigned char *IV, unsigned long IVlen, |
39 | 39 | const unsigned char *adata, unsigned long adatalen, |
40 | 40 | unsigned char *pt, unsigned long ptlen, |
41 | unsigned char *ct, | |
41 | unsigned char *ct, | |
42 | 42 | unsigned char *tag, unsigned long *taglen, |
43 | 43 | int direction) |
44 | 44 | { |
49 | 49 | if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { |
50 | 50 | return err; |
51 | 51 | } |
52 | ||
52 | ||
53 | 53 | if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { |
54 | return | |
54 | return | |
55 | 55 | cipher_descriptor[cipher].accel_gcm_memory |
56 | 56 | (key, keylen, |
57 | 57 | IV, IVlen, |
32 | 32 | gcm->buflen = 0; |
33 | 33 | gcm->totlen = 0; |
34 | 34 | gcm->pttotlen = 0; |
35 | ||
35 | ||
36 | 36 | return CRYPT_OK; |
37 | 37 | } |
38 | 38 |
89 | 89 | |
90 | 90 | /* compute L_$, L_0, L_1, ... */ |
91 | 91 | for (x = -1; x < 32; x++) { |
92 | if (x == -1) { /* gonna compute: L_$ = double(L_*) */ | |
92 | if (x == -1) { /* gonna compute: L_$ = double(L_*) */ | |
93 | 93 | current = ocb->L_dollar; |
94 | 94 | previous = ocb->L_star; |
95 | } | |
96 | else if (x == 0) { /* gonna compute: L_0 = double(L_$) */ | |
95 | } | |
96 | else if (x == 0) { /* gonna compute: L_0 = double(L_$) */ | |
97 | 97 | current = ocb->L_[0]; |
98 | 98 | previous = ocb->L_dollar; |
99 | } | |
100 | else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */ | |
99 | } | |
100 | else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */ | |
101 | 101 | current = ocb->L_[x]; |
102 | 102 | previous = ocb->L_[x-1]; |
103 | } | |
104 | m = previous[0] >> 7; | |
105 | for (y = 0; y < ocb->block_len-1; y++) { | |
106 | current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255; | |
107 | } | |
108 | current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255; | |
109 | if (m == 1) { | |
110 | /* current[] = current[] XOR polys[poly].poly_mul[]*/ | |
111 | ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len); | |
112 | } | |
113 | } | |
103 | } | |
104 | m = previous[0] >> 7; | |
105 | for (y = 0; y < ocb->block_len-1; y++) { | |
106 | current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255; | |
107 | } | |
108 | current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255; | |
109 | if (m == 1) { | |
110 | /* current[] = current[] XOR polys[poly].poly_mul[]*/ | |
111 | ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len); | |
112 | } | |
113 | } | |
114 | 114 | |
115 | /* initialize ocb->Offset_current = Offset_0 */ | |
116 | ocb3_int_calc_offset_zero(ocb, nonce, noncelen); | |
115 | /* initialize ocb->Offset_current = Offset_0 */ | |
116 | ocb3_int_calc_offset_zero(ocb, nonce, noncelen); | |
117 | 117 | |
118 | /* initialize checksum to all zeros */ | |
119 | zeromem(ocb->checksum, ocb->block_len); | |
118 | /* initialize checksum to all zeros */ | |
119 | zeromem(ocb->checksum, ocb->block_len); | |
120 | 120 | |
121 | /* set block index */ | |
122 | ocb->block_index = 1; | |
121 | /* set block index */ | |
122 | ocb->block_index = 1; | |
123 | 123 | |
124 | /* initialize AAD related stuff */ | |
125 | ocb->ablock_index = 1; | |
126 | ocb->adata_buffer_bytes = 0; | |
127 | zeromem(ocb->aOffset_current, ocb->block_len); | |
128 | zeromem(ocb->aSum_current, ocb->block_len); | |
124 | /* initialize AAD related stuff */ | |
125 | ocb->ablock_index = 1; | |
126 | ocb->adata_buffer_bytes = 0; | |
127 | zeromem(ocb->aOffset_current, ocb->block_len); | |
128 | zeromem(ocb->aSum_current, ocb->block_len); | |
129 | 129 | |
130 | return CRYPT_OK; | |
130 | return CRYPT_OK; | |
131 | 131 | } |
132 | 132 | |
133 | 133 | #endif |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @param md2.c |
14 | LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis | |
14 | LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_MD2 |
63 | 63 | L = md->md2.chksum[15]; |
64 | 64 | for (j = 0; j < 16; j++) { |
65 | 65 | |
66 | /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say | |
66 | /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say | |
67 | 67 | otherwise. |
68 | 68 | */ |
69 | 69 | L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255); |
74 | 74 | { |
75 | 75 | int j, k; |
76 | 76 | unsigned char t; |
77 | ||
77 | ||
78 | 78 | /* copy block */ |
79 | 79 | for (j = 0; j < 16; j++) { |
80 | 80 | md->md2.X[16+j] = md->md2.buf[j]; |
121 | 121 | unsigned long n; |
122 | 122 | LTC_ARGCHK(md != NULL); |
123 | 123 | LTC_ARGCHK(in != NULL); |
124 | if (md-> md2 .curlen > sizeof(md-> md2 .buf)) { | |
125 | return CRYPT_INVALID_ARG; | |
126 | } | |
124 | if (md-> md2 .curlen > sizeof(md-> md2 .buf)) { | |
125 | return CRYPT_INVALID_ARG; | |
126 | } | |
127 | 127 | while (inlen > 0) { |
128 | 128 | n = MIN(inlen, (16 - md->md2.curlen)); |
129 | 129 | XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n); |
185 | 185 | /** |
186 | 186 | Self-test the hash |
187 | 187 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
188 | */ | |
188 | */ | |
189 | 189 | int md2_test(void) |
190 | 190 | { |
191 | 191 | #ifndef LTC_TEST |
192 | 192 | return CRYPT_NOP; |
193 | #else | |
193 | #else | |
194 | 194 | static const struct { |
195 | 195 | char *msg; |
196 | 196 | unsigned char md[16]; |
238 | 238 | return CRYPT_FAIL_TESTVECTOR; |
239 | 239 | } |
240 | 240 | } |
241 | return CRYPT_OK; | |
241 | return CRYPT_OK; | |
242 | 242 | #endif |
243 | 243 | } |
244 | 244 |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @param md4.c |
14 | Submitted by Dobes Vandermeer (dobes@smartt.com) | |
14 | Submitted by Dobes Vandermeer (dobes@smartt.com) | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_MD4 |
22 | 22 | 6, |
23 | 23 | 16, |
24 | 24 | 64, |
25 | ||
25 | ||
26 | 26 | /* OID */ |
27 | 27 | { 1, 2, 840, 113549, 2, 4, }, |
28 | 28 | 6, |
55 | 55 | /* ROTATE_LEFT rotates x left n bits. */ |
56 | 56 | #define ROTATE_LEFT(x, n) ROLc(x, n) |
57 | 57 | |
58 | /* FF, GG and HH are transformations for rounds 1, 2 and 3 */ | |
59 | /* Rotation is separate from addition to prevent recomputation */ | |
58 | /* FF, GG and HH are transformations for rounds 1, 2 and 3 */ | |
59 | /* Rotation is separate from addition to prevent recomputation */ | |
60 | 60 | |
61 | 61 | #define FF(a, b, c, d, x, s) { \ |
62 | 62 | (a) += F ((b), (c), (d)) + (x); \ |
90 | 90 | for (i = 0; i < 16; i++) { |
91 | 91 | LOAD32L(x[i], buf + (4*i)); |
92 | 92 | } |
93 | ||
94 | /* Round 1 */ | |
95 | FF (a, b, c, d, x[ 0], S11); /* 1 */ | |
96 | FF (d, a, b, c, x[ 1], S12); /* 2 */ | |
97 | FF (c, d, a, b, x[ 2], S13); /* 3 */ | |
98 | FF (b, c, d, a, x[ 3], S14); /* 4 */ | |
99 | FF (a, b, c, d, x[ 4], S11); /* 5 */ | |
100 | FF (d, a, b, c, x[ 5], S12); /* 6 */ | |
101 | FF (c, d, a, b, x[ 6], S13); /* 7 */ | |
102 | FF (b, c, d, a, x[ 7], S14); /* 8 */ | |
103 | FF (a, b, c, d, x[ 8], S11); /* 9 */ | |
93 | ||
94 | /* Round 1 */ | |
95 | FF (a, b, c, d, x[ 0], S11); /* 1 */ | |
96 | FF (d, a, b, c, x[ 1], S12); /* 2 */ | |
97 | FF (c, d, a, b, x[ 2], S13); /* 3 */ | |
98 | FF (b, c, d, a, x[ 3], S14); /* 4 */ | |
99 | FF (a, b, c, d, x[ 4], S11); /* 5 */ | |
100 | FF (d, a, b, c, x[ 5], S12); /* 6 */ | |
101 | FF (c, d, a, b, x[ 6], S13); /* 7 */ | |
102 | FF (b, c, d, a, x[ 7], S14); /* 8 */ | |
103 | FF (a, b, c, d, x[ 8], S11); /* 9 */ | |
104 | 104 | FF (d, a, b, c, x[ 9], S12); /* 10 */ |
105 | FF (c, d, a, b, x[10], S13); /* 11 */ | |
105 | FF (c, d, a, b, x[10], S13); /* 11 */ | |
106 | 106 | FF (b, c, d, a, x[11], S14); /* 12 */ |
107 | 107 | FF (a, b, c, d, x[12], S11); /* 13 */ |
108 | FF (d, a, b, c, x[13], S12); /* 14 */ | |
109 | FF (c, d, a, b, x[14], S13); /* 15 */ | |
110 | FF (b, c, d, a, x[15], S14); /* 16 */ | |
111 | ||
112 | /* Round 2 */ | |
113 | GG (a, b, c, d, x[ 0], S21); /* 17 */ | |
114 | GG (d, a, b, c, x[ 4], S22); /* 18 */ | |
115 | GG (c, d, a, b, x[ 8], S23); /* 19 */ | |
116 | GG (b, c, d, a, x[12], S24); /* 20 */ | |
117 | GG (a, b, c, d, x[ 1], S21); /* 21 */ | |
118 | GG (d, a, b, c, x[ 5], S22); /* 22 */ | |
119 | GG (c, d, a, b, x[ 9], S23); /* 23 */ | |
120 | GG (b, c, d, a, x[13], S24); /* 24 */ | |
121 | GG (a, b, c, d, x[ 2], S21); /* 25 */ | |
122 | GG (d, a, b, c, x[ 6], S22); /* 26 */ | |
123 | GG (c, d, a, b, x[10], S23); /* 27 */ | |
124 | GG (b, c, d, a, x[14], S24); /* 28 */ | |
125 | GG (a, b, c, d, x[ 3], S21); /* 29 */ | |
126 | GG (d, a, b, c, x[ 7], S22); /* 30 */ | |
127 | GG (c, d, a, b, x[11], S23); /* 31 */ | |
128 | GG (b, c, d, a, x[15], S24); /* 32 */ | |
129 | ||
108 | FF (d, a, b, c, x[13], S12); /* 14 */ | |
109 | FF (c, d, a, b, x[14], S13); /* 15 */ | |
110 | FF (b, c, d, a, x[15], S14); /* 16 */ | |
111 | ||
112 | /* Round 2 */ | |
113 | GG (a, b, c, d, x[ 0], S21); /* 17 */ | |
114 | GG (d, a, b, c, x[ 4], S22); /* 18 */ | |
115 | GG (c, d, a, b, x[ 8], S23); /* 19 */ | |
116 | GG (b, c, d, a, x[12], S24); /* 20 */ | |
117 | GG (a, b, c, d, x[ 1], S21); /* 21 */ | |
118 | GG (d, a, b, c, x[ 5], S22); /* 22 */ | |
119 | GG (c, d, a, b, x[ 9], S23); /* 23 */ | |
120 | GG (b, c, d, a, x[13], S24); /* 24 */ | |
121 | GG (a, b, c, d, x[ 2], S21); /* 25 */ | |
122 | GG (d, a, b, c, x[ 6], S22); /* 26 */ | |
123 | GG (c, d, a, b, x[10], S23); /* 27 */ | |
124 | GG (b, c, d, a, x[14], S24); /* 28 */ | |
125 | GG (a, b, c, d, x[ 3], S21); /* 29 */ | |
126 | GG (d, a, b, c, x[ 7], S22); /* 30 */ | |
127 | GG (c, d, a, b, x[11], S23); /* 31 */ | |
128 | GG (b, c, d, a, x[15], S24); /* 32 */ | |
129 | ||
130 | 130 | /* Round 3 */ |
131 | HH (a, b, c, d, x[ 0], S31); /* 33 */ | |
132 | HH (d, a, b, c, x[ 8], S32); /* 34 */ | |
133 | HH (c, d, a, b, x[ 4], S33); /* 35 */ | |
134 | HH (b, c, d, a, x[12], S34); /* 36 */ | |
135 | HH (a, b, c, d, x[ 2], S31); /* 37 */ | |
136 | HH (d, a, b, c, x[10], S32); /* 38 */ | |
137 | HH (c, d, a, b, x[ 6], S33); /* 39 */ | |
138 | HH (b, c, d, a, x[14], S34); /* 40 */ | |
139 | HH (a, b, c, d, x[ 1], S31); /* 41 */ | |
140 | HH (d, a, b, c, x[ 9], S32); /* 42 */ | |
141 | HH (c, d, a, b, x[ 5], S33); /* 43 */ | |
142 | HH (b, c, d, a, x[13], S34); /* 44 */ | |
143 | HH (a, b, c, d, x[ 3], S31); /* 45 */ | |
144 | HH (d, a, b, c, x[11], S32); /* 46 */ | |
145 | HH (c, d, a, b, x[ 7], S33); /* 47 */ | |
146 | HH (b, c, d, a, x[15], S34); /* 48 */ | |
147 | ||
131 | HH (a, b, c, d, x[ 0], S31); /* 33 */ | |
132 | HH (d, a, b, c, x[ 8], S32); /* 34 */ | |
133 | HH (c, d, a, b, x[ 4], S33); /* 35 */ | |
134 | HH (b, c, d, a, x[12], S34); /* 36 */ | |
135 | HH (a, b, c, d, x[ 2], S31); /* 37 */ | |
136 | HH (d, a, b, c, x[10], S32); /* 38 */ | |
137 | HH (c, d, a, b, x[ 6], S33); /* 39 */ | |
138 | HH (b, c, d, a, x[14], S34); /* 40 */ | |
139 | HH (a, b, c, d, x[ 1], S31); /* 41 */ | |
140 | HH (d, a, b, c, x[ 9], S32); /* 42 */ | |
141 | HH (c, d, a, b, x[ 5], S33); /* 43 */ | |
142 | HH (b, c, d, a, x[13], S34); /* 44 */ | |
143 | HH (a, b, c, d, x[ 3], S31); /* 45 */ | |
144 | HH (d, a, b, c, x[11], S32); /* 46 */ | |
145 | HH (c, d, a, b, x[ 7], S33); /* 47 */ | |
146 | HH (b, c, d, a, x[15], S34); /* 48 */ | |
147 | ||
148 | 148 | |
149 | 149 | /* Update our state */ |
150 | 150 | md->md4.state[0] = md->md4.state[0] + a; |
241 | 241 | } |
242 | 242 | #ifdef LTC_CLEAN_STACK |
243 | 243 | zeromem(md, sizeof(hash_state)); |
244 | #endif | |
244 | #endif | |
245 | 245 | return CRYPT_OK; |
246 | 246 | } |
247 | 247 | |
248 | 248 | /** |
249 | 249 | Self-test the hash |
250 | 250 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
251 | */ | |
251 | */ | |
252 | 252 | int md4_test(void) |
253 | 253 | { |
254 | 254 | #ifndef LTC_TEST |
255 | 255 | return CRYPT_NOP; |
256 | #else | |
256 | #else | |
257 | 257 | static const struct md4_test_case { |
258 | 258 | char *input; |
259 | 259 | unsigned char digest[16]; |
260 | 260 | } cases[] = { |
261 | { "", | |
261 | { "", | |
262 | 262 | {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, |
263 | 263 | 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} }, |
264 | 264 | { "a", |
265 | 265 | {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, |
266 | 266 | 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} }, |
267 | 267 | { "abc", |
268 | {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, | |
268 | {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, | |
269 | 269 | 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} }, |
270 | { "message digest", | |
271 | {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, | |
270 | { "message digest", | |
271 | {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, | |
272 | 272 | 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} }, |
273 | { "abcdefghijklmnopqrstuvwxyz", | |
274 | {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, | |
273 | { "abcdefghijklmnopqrstuvwxyz", | |
274 | {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, | |
275 | 275 | 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} }, |
276 | { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", | |
277 | {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, | |
276 | { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", | |
277 | {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, | |
278 | 278 | 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} }, |
279 | { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", | |
280 | {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, | |
279 | { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", | |
280 | {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, | |
281 | 281 | 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} }, |
282 | 282 | }; |
283 | 283 | int i; |
12 | 12 | |
13 | 13 | /** |
14 | 14 | @file md5.c |
15 | LTC_MD5 hash function by Tom St Denis | |
15 | LTC_MD5 hash function by Tom St Denis | |
16 | 16 | */ |
17 | 17 | |
18 | 18 | #ifdef LTC_MD5 |
94 | 94 | a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; |
95 | 95 | |
96 | 96 | |
97 | #endif | |
97 | #endif | |
98 | 98 | |
99 | 99 | #ifdef LTC_CLEAN_STACK |
100 | 100 | static int _md5_compress(hash_state *md, unsigned char *buf) |
111 | 111 | for (i = 0; i < 16; i++) { |
112 | 112 | LOAD32L(W[i], buf + (4*i)); |
113 | 113 | } |
114 | ||
114 | ||
115 | 115 | /* copy state */ |
116 | 116 | a = md->md5.state[0]; |
117 | 117 | b = md->md5.state[1]; |
308 | 308 | /** |
309 | 309 | Self-test the hash |
310 | 310 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
311 | */ | |
311 | */ | |
312 | 312 | int md5_test(void) |
313 | 313 | { |
314 | 314 | #ifndef LTC_TEST |
315 | 315 | return CRYPT_NOP; |
316 | #else | |
316 | #else | |
317 | 317 | static const struct { |
318 | 318 | char *msg; |
319 | 319 | unsigned char hash[16]; |
320 | 320 | } tests[] = { |
321 | 321 | { "", |
322 | { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, | |
322 | { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, | |
323 | 323 | 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, |
324 | 324 | { "a", |
325 | {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, | |
325 | {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, | |
326 | 326 | 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, |
327 | 327 | { "abc", |
328 | { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, | |
328 | { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, | |
329 | 329 | 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, |
330 | { "message digest", | |
331 | { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, | |
332 | 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, | |
330 | { "message digest", | |
331 | { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, | |
332 | 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, | |
333 | 333 | { "abcdefghijklmnopqrstuvwxyz", |
334 | { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, | |
334 | { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, | |
335 | 335 | 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, |
336 | 336 | { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", |
337 | { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, | |
337 | { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, | |
338 | 338 | 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, |
339 | 339 | { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", |
340 | { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, | |
341 | 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, | |
340 | { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, | |
341 | 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, | |
342 | 342 | { NULL, { 0 } } |
343 | 343 | }; |
344 | 344 |
12 | 12 | /** |
13 | 13 | @param rmd128.c |
14 | 14 | RMD128 Hash function |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | /* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC |
18 | 18 | * |
41 | 41 | }; |
42 | 42 | |
43 | 43 | /* the four basic functions F(), G() and H() */ |
44 | #define F(x, y, z) ((x) ^ (y) ^ (z)) | |
45 | #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) | |
44 | #define F(x, y, z) ((x) ^ (y) ^ (z)) | |
45 | #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) | |
46 | 46 | #define H(x, y, z) (((x) | ~(y)) ^ (z)) |
47 | #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) | |
48 | ||
47 | #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) | |
48 | ||
49 | 49 | /* the eight basic operations FF() through III() */ |
50 | 50 | #define FF(a, b, c, d, x, s) \ |
51 | 51 | (a) += F((b), (c), (d)) + (x);\ |
87 | 87 | { |
88 | 88 | ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; |
89 | 89 | int i; |
90 | ||
90 | ||
91 | 91 | /* load words X */ |
92 | 92 | for (i = 0; i < 16; i++){ |
93 | 93 | LOAD32L(X[i], buf + (4 * i)); |
116 | 116 | FF(dd, aa, bb, cc, X[13], 7); |
117 | 117 | FF(cc, dd, aa, bb, X[14], 9); |
118 | 118 | FF(bb, cc, dd, aa, X[15], 8); |
119 | ||
119 | ||
120 | 120 | /* round 2 */ |
121 | 121 | GG(aa, bb, cc, dd, X[ 7], 7); |
122 | 122 | GG(dd, aa, bb, cc, X[ 4], 6); |
172 | 172 | II(bb, cc, dd, aa, X[ 2], 12); |
173 | 173 | |
174 | 174 | /* parallel round 1 */ |
175 | III(aaa, bbb, ccc, ddd, X[ 5], 8); | |
175 | III(aaa, bbb, ccc, ddd, X[ 5], 8); | |
176 | 176 | III(ddd, aaa, bbb, ccc, X[14], 9); |
177 | 177 | III(ccc, ddd, aaa, bbb, X[ 7], 9); |
178 | 178 | III(bbb, ccc, ddd, aaa, X[ 0], 11); |
207 | 207 | HHH(ccc, ddd, aaa, bbb, X[ 1], 13); |
208 | 208 | HHH(bbb, ccc, ddd, aaa, X[ 2], 11); |
209 | 209 | |
210 | /* parallel round 3 */ | |
210 | /* parallel round 3 */ | |
211 | 211 | GGG(aaa, bbb, ccc, ddd, X[15], 9); |
212 | 212 | GGG(ddd, aaa, bbb, ccc, X[ 5], 7); |
213 | 213 | GGG(ccc, ddd, aaa, bbb, X[ 1], 15); |
341 | 341 | #ifdef LTC_CLEAN_STACK |
342 | 342 | zeromem(md, sizeof(hash_state)); |
343 | 343 | #endif |
344 | return CRYPT_OK; | |
344 | return CRYPT_OK; | |
345 | 345 | } |
346 | 346 | |
347 | 347 | /** |
348 | 348 | Self-test the hash |
349 | 349 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
350 | */ | |
350 | */ | |
351 | 351 | int rmd128_test(void) |
352 | 352 | { |
353 | 353 | #ifndef LTC_TEST |
12 | 12 | /** |
13 | 13 | @file rmd160.c |
14 | 14 | RMD160 hash function |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | /* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC |
18 | 18 | * |
41 | 41 | }; |
42 | 42 | |
43 | 43 | /* the five basic functions F(), G() and H() */ |
44 | #define F(x, y, z) ((x) ^ (y) ^ (z)) | |
45 | #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) | |
44 | #define F(x, y, z) ((x) ^ (y) ^ (z)) | |
45 | #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) | |
46 | 46 | #define H(x, y, z) (((x) | ~(y)) ^ (z)) |
47 | #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) | |
47 | #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) | |
48 | 48 | #define J(x, y, z) ((x) ^ ((y) | ~(z))) |
49 | ||
49 | ||
50 | 50 | /* the ten basic operations FF() through III() */ |
51 | 51 | #define FF(a, b, c, d, e, x, s) \ |
52 | 52 | (a) += F((b), (c), (d)) + (x);\ |
137 | 137 | FF(cc, dd, ee, aa, bb, X[13], 7); |
138 | 138 | FF(bb, cc, dd, ee, aa, X[14], 9); |
139 | 139 | FF(aa, bb, cc, dd, ee, X[15], 8); |
140 | ||
140 | ||
141 | 141 | /* round 2 */ |
142 | 142 | GG(ee, aa, bb, cc, dd, X[ 7], 7); |
143 | 143 | GG(dd, ee, aa, bb, cc, X[ 4], 6); |
229 | 229 | JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); |
230 | 230 | |
231 | 231 | /* parallel round 2 */ |
232 | III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); | |
232 | III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); | |
233 | 233 | III(ddd, eee, aaa, bbb, ccc, X[11], 13); |
234 | 234 | III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); |
235 | 235 | III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); |
264 | 264 | HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); |
265 | 265 | HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); |
266 | 266 | |
267 | /* parallel round 4 */ | |
267 | /* parallel round 4 */ | |
268 | 268 | GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); |
269 | 269 | GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); |
270 | 270 | GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); |
406 | 406 | /** |
407 | 407 | Self-test the hash |
408 | 408 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
409 | */ | |
409 | */ | |
410 | 410 | int rmd160_test(void) |
411 | 411 | { |
412 | 412 | #ifndef LTC_TEST |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file sha1.c |
14 | LTC_SHA1 code by Tom St Denis | |
14 | LTC_SHA1 code by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | |
65 | 65 | |
66 | 66 | /* expand it */ |
67 | 67 | for (i = 16; i < 80; i++) { |
68 | W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); | |
68 | W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); | |
69 | 69 | } |
70 | 70 | |
71 | 71 | /* compress */ |
74 | 74 | #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); |
75 | 75 | #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); |
76 | 76 | #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); |
77 | ||
77 | ||
78 | 78 | #ifdef LTC_SMALL_CODE |
79 | ||
79 | ||
80 | 80 | for (i = 0; i < 20; ) { |
81 | 81 | FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; |
82 | 82 | } |
104 | 104 | } |
105 | 105 | |
106 | 106 | /* round two */ |
107 | for (; i < 40; ) { | |
107 | for (; i < 40; ) { | |
108 | 108 | FF1(a,b,c,d,e,i++); |
109 | 109 | FF1(e,a,b,c,d,i++); |
110 | 110 | FF1(d,e,a,b,c,i++); |
113 | 113 | } |
114 | 114 | |
115 | 115 | /* round three */ |
116 | for (; i < 60; ) { | |
116 | for (; i < 60; ) { | |
117 | 117 | FF2(a,b,c,d,e,i++); |
118 | 118 | FF2(e,a,b,c,d,i++); |
119 | 119 | FF2(d,e,a,b,c,i++); |
122 | 122 | } |
123 | 123 | |
124 | 124 | /* round four */ |
125 | for (; i < 80; ) { | |
125 | for (; i < 80; ) { | |
126 | 126 | FF3(a,b,c,d,e,i++); |
127 | 127 | FF3(e,a,b,c,d,i++); |
128 | 128 | FF3(d,e,a,b,c,i++); |
240 | 240 | /** |
241 | 241 | Self-test the hash |
242 | 242 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
243 | */ | |
243 | */ | |
244 | 244 | int sha1_test(void) |
245 | 245 | { |
246 | 246 | #ifndef LTC_TEST |
247 | 247 | return CRYPT_NOP; |
248 | #else | |
248 | #else | |
249 | 249 | static const struct { |
250 | 250 | char *msg; |
251 | 251 | unsigned char hash[20]; |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file sha256.c |
14 | LTC_SHA256 by Tom St Denis | |
15 | */ | |
16 | ||
17 | #ifdef LTC_SHA256 | |
14 | LTC_SHA256 by Tom St Denis | |
15 | */ | |
16 | ||
17 | #ifdef LTC_SHA256 | |
18 | 18 | |
19 | 19 | const struct ltc_hash_descriptor sha256_desc = |
20 | 20 | { |
26 | 26 | /* OID */ |
27 | 27 | { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, |
28 | 28 | 9, |
29 | ||
29 | ||
30 | 30 | &sha256_init, |
31 | 31 | &sha256_process, |
32 | 32 | &sha256_done, |
55 | 55 | |
56 | 56 | /* Various logical functions */ |
57 | 57 | #define Ch(x,y,z) (z ^ (x & (y ^ z))) |
58 | #define Maj(x,y,z) (((x | y) & z) | (x & y)) | |
58 | #define Maj(x,y,z) (((x | y) & z) | (x & y)) | |
59 | 59 | #define S(x, n) RORc((x),(n)) |
60 | 60 | #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) |
61 | 61 | #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) |
89 | 89 | /* fill W[16..63] */ |
90 | 90 | for (i = 16; i < 64; i++) { |
91 | 91 | W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; |
92 | } | |
92 | } | |
93 | 93 | |
94 | 94 | /* Compress */ |
95 | #ifdef LTC_SMALL_CODE | |
95 | #ifdef LTC_SMALL_CODE | |
96 | 96 | #define RND(a,b,c,d,e,f,g,h,i) \ |
97 | 97 | t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ |
98 | 98 | t1 = Sigma0(a) + Maj(a, b, c); \ |
101 | 101 | |
102 | 102 | for (i = 0; i < 64; ++i) { |
103 | 103 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); |
104 | t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; | |
104 | t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; | |
105 | 105 | S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; |
106 | } | |
107 | #else | |
106 | } | |
107 | #else | |
108 | 108 | #define RND(a,b,c,d,e,f,g,h,i,ki) \ |
109 | 109 | t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ |
110 | 110 | t1 = Sigma0(a) + Maj(a, b, c); \ |
176 | 176 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); |
177 | 177 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); |
178 | 178 | |
179 | #undef RND | |
180 | ||
181 | #endif | |
179 | #undef RND | |
180 | ||
181 | #endif | |
182 | 182 | |
183 | 183 | /* feedback */ |
184 | 184 | for (i = 0; i < 8; i++) { |
286 | 286 | /** |
287 | 287 | Self-test the hash |
288 | 288 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
289 | */ | |
289 | */ | |
290 | 290 | int sha256_test(void) |
291 | 291 | { |
292 | 292 | #ifndef LTC_TEST |
293 | 293 | return CRYPT_NOP; |
294 | #else | |
294 | #else | |
295 | 295 | static const struct { |
296 | 296 | char *msg; |
297 | 297 | unsigned char hash[32]; |
303 | 303 | 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } |
304 | 304 | }, |
305 | 305 | { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", |
306 | { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, | |
306 | { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, | |
307 | 307 | 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, |
308 | 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, | |
308 | 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, | |
309 | 309 | 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } |
310 | 310 | }, |
311 | 311 | }; |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @param sha512.c |
14 | LTC_SHA512 by Tom St Denis | |
14 | LTC_SHA512 by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_SHA512 |
36 | 36 | |
37 | 37 | /* the K array */ |
38 | 38 | static const ulong64 K[80] = { |
39 | CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), | |
39 | CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), | |
40 | 40 | CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), |
41 | CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), | |
41 | CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), | |
42 | 42 | CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118), |
43 | CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), | |
43 | CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), | |
44 | 44 | CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2), |
45 | CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), | |
45 | CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), | |
46 | 46 | CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694), |
47 | CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), | |
47 | CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), | |
48 | 48 | CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65), |
49 | CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), | |
49 | CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), | |
50 | 50 | CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5), |
51 | CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), | |
51 | CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), | |
52 | 52 | CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4), |
53 | CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), | |
53 | CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), | |
54 | 54 | CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70), |
55 | CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), | |
55 | CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), | |
56 | 56 | CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df), |
57 | CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), | |
57 | CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), | |
58 | 58 | CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b), |
59 | 59 | CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001), |
60 | 60 | CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30), |
61 | CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), | |
61 | CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), | |
62 | 62 | CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8), |
63 | CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), | |
63 | CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), | |
64 | 64 | CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8), |
65 | CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), | |
65 | CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), | |
66 | 66 | CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3), |
67 | CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), | |
67 | CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), | |
68 | 68 | CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec), |
69 | CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), | |
69 | CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), | |
70 | 70 | CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b), |
71 | CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), | |
71 | CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), | |
72 | 72 | CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178), |
73 | CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), | |
73 | CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), | |
74 | 74 | CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b), |
75 | CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), | |
75 | CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), | |
76 | 76 | CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c), |
77 | CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), | |
77 | CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), | |
78 | 78 | CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) |
79 | 79 | }; |
80 | 80 | |
81 | 81 | /* Various logical functions */ |
82 | 82 | #define Ch(x,y,z) (z ^ (x & (y ^ z))) |
83 | #define Maj(x,y,z) (((x | y) & z) | (x & y)) | |
83 | #define Maj(x,y,z) (((x | y) & z) | (x & y)) | |
84 | 84 | #define S(x, n) ROR64c(x, n) |
85 | 85 | #define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) |
86 | 86 | #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) |
111 | 111 | /* fill W[16..79] */ |
112 | 112 | for (i = 16; i < 80; i++) { |
113 | 113 | W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; |
114 | } | |
114 | } | |
115 | 115 | |
116 | 116 | /* Compress */ |
117 | 117 | #ifdef LTC_SMALL_CODE |
134 | 134 | d += t0; \ |
135 | 135 | h = t0 + t1; |
136 | 136 | |
137 | for (i = 0; i < 80; i += 8) { | |
138 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); | |
139 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); | |
140 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); | |
141 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); | |
142 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); | |
143 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); | |
144 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); | |
145 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); | |
146 | } | |
147 | #endif | |
137 | for (i = 0; i < 80; i += 8) { | |
138 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); | |
139 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); | |
140 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); | |
141 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); | |
142 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); | |
143 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); | |
144 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); | |
145 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); | |
146 | } | |
147 | #endif | |
148 | 148 | |
149 | 149 | |
150 | 150 | /* feedback */ |
231 | 231 | md->sha512.curlen = 0; |
232 | 232 | } |
233 | 233 | |
234 | /* pad upto 120 bytes of zeroes | |
234 | /* pad upto 120 bytes of zeroes | |
235 | 235 | * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash |
236 | 236 | * > 2^64 bits of data... :-) |
237 | 237 | */ |
256 | 256 | /** |
257 | 257 | Self-test the hash |
258 | 258 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
259 | */ | |
259 | */ | |
260 | 260 | int sha512_test(void) |
261 | 261 | { |
262 | 262 | #ifndef LTC_TEST |
263 | 263 | return CRYPT_NOP; |
264 | #else | |
264 | #else | |
265 | 265 | static const struct { |
266 | 266 | char *msg; |
267 | 267 | unsigned char hash[64]; |
557 | 557 | #ifdef _MSC_VER |
558 | 558 | #define INLINE __inline |
559 | 559 | #else |
560 | #define INLINE | |
561 | #endif | |
560 | #define INLINE | |
561 | #endif | |
562 | 562 | |
563 | 563 | /* one round of the hash function */ |
564 | 564 | INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) |
565 | 565 | { |
566 | 566 | ulong64 tmp; |
567 | tmp = (*c ^= x); | |
568 | *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)]; | |
569 | tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); | |
567 | tmp = (*c ^= x); | |
568 | *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)]; | |
569 | tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); | |
570 | 570 | switch (mul) { |
571 | 571 | case 5: *b = (tmp << 2) + tmp; break; |
572 | 572 | case 7: *b = (tmp << 3) - tmp; break; |
577 | 577 | /* one complete pass */ |
578 | 578 | static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul) |
579 | 579 | { |
580 | tiger_round(a,b,c,x[0],mul); | |
581 | tiger_round(b,c,a,x[1],mul); | |
582 | tiger_round(c,a,b,x[2],mul); | |
583 | tiger_round(a,b,c,x[3],mul); | |
584 | tiger_round(b,c,a,x[4],mul); | |
585 | tiger_round(c,a,b,x[5],mul); | |
586 | tiger_round(a,b,c,x[6],mul); | |
587 | tiger_round(b,c,a,x[7],mul); | |
588 | } | |
580 | tiger_round(a,b,c,x[0],mul); | |
581 | tiger_round(b,c,a,x[1],mul); | |
582 | tiger_round(c,a,b,x[2],mul); | |
583 | tiger_round(a,b,c,x[3],mul); | |
584 | tiger_round(b,c,a,x[4],mul); | |
585 | tiger_round(c,a,b,x[5],mul); | |
586 | tiger_round(a,b,c,x[6],mul); | |
587 | tiger_round(b,c,a,x[7],mul); | |
588 | } | |
589 | 589 | |
590 | 590 | /* The key mixing schedule */ |
591 | static void key_schedule(ulong64 *x) | |
591 | static void key_schedule(ulong64 *x) | |
592 | 592 | { |
593 | x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); | |
594 | x[1] ^= x[0]; | |
595 | x[2] += x[1]; | |
596 | x[3] -= x[2] ^ ((~x[1])<<19); | |
597 | x[4] ^= x[3]; | |
598 | x[5] += x[4]; | |
599 | x[6] -= x[5] ^ ((~x[4])>>23); | |
600 | x[7] ^= x[6]; | |
601 | x[0] += x[7]; | |
602 | x[1] -= x[0] ^ ((~x[7])<<19); | |
603 | x[2] ^= x[1]; | |
604 | x[3] += x[2]; | |
605 | x[4] -= x[3] ^ ((~x[2])>>23); | |
606 | x[5] ^= x[4]; | |
607 | x[6] += x[5]; | |
593 | x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); | |
594 | x[1] ^= x[0]; | |
595 | x[2] += x[1]; | |
596 | x[3] -= x[2] ^ ((~x[1])<<19); | |
597 | x[4] ^= x[3]; | |
598 | x[5] += x[4]; | |
599 | x[6] -= x[5] ^ ((~x[4])>>23); | |
600 | x[7] ^= x[6]; | |
601 | x[0] += x[7]; | |
602 | x[1] -= x[0] ^ ((~x[7])<<19); | |
603 | x[2] ^= x[1]; | |
604 | x[3] += x[2]; | |
605 | x[4] -= x[3] ^ ((~x[2])>>23); | |
606 | x[5] ^= x[4]; | |
607 | x[6] += x[5]; | |
608 | 608 | x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF); |
609 | } | |
609 | } | |
610 | 610 | |
611 | 611 | #ifdef LTC_CLEAN_STACK |
612 | 612 | static int _tiger_compress(hash_state *md, unsigned char *buf) |
708 | 708 | |
709 | 709 | /* pad upto 56 bytes of zeroes */ |
710 | 710 | while (md->tiger.curlen < 56) { |
711 | md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; | |
711 | md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; | |
712 | 712 | } |
713 | 713 | |
714 | 714 | /* store length */ |
729 | 729 | /** |
730 | 730 | Self-test the hash |
731 | 731 | @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled |
732 | */ | |
732 | */ | |
733 | 733 | int tiger_test(void) |
734 | 734 | { |
735 | 735 | #ifndef LTC_TEST |
736 | 736 | return CRYPT_NOP; |
737 | #else | |
737 | #else | |
738 | 738 | static const struct { |
739 | 739 | char *msg; |
740 | 740 | unsigned char hash[24]; |
61 | 61 | out[x] = f9->ACC[x]; |
62 | 62 | } |
63 | 63 | *outlen = x; |
64 | ||
64 | ||
65 | 65 | #ifdef LTC_CLEAN_STACK |
66 | 66 | zeromem(f9, sizeof(*f9)); |
67 | 67 | #endif |
44 | 44 | if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &f9->key)) != CRYPT_OK) { |
45 | 45 | goto done; |
46 | 46 | } |
47 | ||
47 | ||
48 | 48 | /* make the second key */ |
49 | 49 | for (x = 0; (unsigned)x < keylen; x++) { |
50 | 50 | f9->akey[x] = key[x] ^ 0xAA; |
51 | 51 | } |
52 | ||
52 | ||
53 | 53 | /* setup struct */ |
54 | 54 | zeromem(f9->IV, cipher_descriptor[cipher].block_length); |
55 | 55 | zeromem(f9->ACC, cipher_descriptor[cipher].block_length); |
16 | 16 | |
17 | 17 | #ifdef LTC_F9_MODE |
18 | 18 | |
19 | /** f9-MAC a block of memory | |
19 | /** f9-MAC a block of memory | |
20 | 20 | @param cipher Index of cipher to use |
21 | 21 | @param key [in] Secret key |
22 | 22 | @param keylen Length of key in octets |
26 | 26 | @param outlen [in/out] Output size and final tag size |
27 | 27 | Return CRYPT_OK on success. |
28 | 28 | */ |
29 | int f9_memory(int cipher, | |
29 | int f9_memory(int cipher, | |
30 | 30 | const unsigned char *key, unsigned long keylen, |
31 | 31 | const unsigned char *in, unsigned long inlen, |
32 | 32 | unsigned char *out, unsigned long *outlen) |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | #include <stdarg.h> |
12 | 12 | |
13 | /** | |
13 | /** | |
14 | 14 | @file f9_memory_multi.c |
15 | 15 | f9 support, process multiple blocks of memory, Tom St Denis |
16 | 16 | */ |
18 | 18 | #ifdef LTC_F9_MODE |
19 | 19 | |
20 | 20 | /** |
21 | f9 multiple blocks of memory | |
21 | f9 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) |
29 | 29 | @param ... tuples of (data,len) pairs to f9, terminated with a (NULL,x) (x=don't care) |
30 | 30 | @return CRYPT_OK if successful |
31 | 31 | */ |
32 | int f9_memory_multi(int cipher, | |
32 | int f9_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(f9); |
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 pelican_memory.c |
14 | Pelican MAC, MAC a block of memory, by Tom St Denis | |
14 | Pelican MAC, MAC a block of memory, by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PELICAN |
22 | 22 | @param keylen The length of the key (octets) |
23 | 23 | @param in The input to MAC |
24 | 24 | @param inlen The length of the input (octets) |
25 | @param out [out] The output TAG | |
25 | @param out [out] The output TAG | |
26 | 26 | @return CRYPT_OK on success |
27 | 27 | */ |
28 | 28 | int pelican_memory(const unsigned char *key, unsigned long keylen, |
33 | 33 | int err; |
34 | 34 | |
35 | 35 | pel = XMALLOC(sizeof(*pel)); |
36 | if (pel == NULL) { | |
36 | if (pel == NULL) { | |
37 | 37 | return CRYPT_MEM; |
38 | 38 | } |
39 | 39 | |
46 | 46 | return err; |
47 | 47 | } |
48 | 48 | err = pelican_done(pel, out); |
49 | XFREE(pel); | |
49 | XFREE(pel); | |
50 | 50 | return err; |
51 | 51 | } |
52 | 52 |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pmac_done.c |
14 | PMAC implementation, terminate a session, by Tom St Denis | |
14 | PMAC implementation, terminate a session, by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PMAC |
109 | 109 | } |
110 | 110 | } |
111 | 111 | |
112 | /* find Lr = L / x */ | |
113 | m = L[pmac->block_len-1] & 1; | |
112 | /* find Lr = L / x */ | |
113 | m = L[pmac->block_len-1] & 1; | |
114 | 114 | |
115 | /* shift right */ | |
116 | for (x = pmac->block_len - 1; x > 0; x--) { | |
117 | pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255; | |
118 | } | |
119 | pmac->Lr[0] = L[0] >> 1; | |
115 | /* shift right */ | |
116 | for (x = pmac->block_len - 1; x > 0; x--) { | |
117 | pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255; | |
118 | } | |
119 | pmac->Lr[0] = L[0] >> 1; | |
120 | 120 | |
121 | if (m == 1) { | |
122 | for (x = 0; x < pmac->block_len; x++) { | |
123 | pmac->Lr[x] ^= polys[poly].poly_div[x]; | |
124 | } | |
125 | } | |
121 | if (m == 1) { | |
122 | for (x = 0; x < pmac->block_len; x++) { | |
123 | pmac->Lr[x] ^= polys[poly].poly_div[x]; | |
124 | } | |
125 | } | |
126 | 126 | |
127 | /* zero buffer, counters, etc... */ | |
128 | pmac->block_index = 1; | |
129 | pmac->cipher_idx = cipher; | |
130 | pmac->buflen = 0; | |
131 | zeromem(pmac->block, sizeof(pmac->block)); | |
132 | zeromem(pmac->Li, sizeof(pmac->Li)); | |
133 | zeromem(pmac->checksum, sizeof(pmac->checksum)); | |
134 | err = CRYPT_OK; | |
127 | /* zero buffer, counters, etc... */ | |
128 | pmac->block_index = 1; | |
129 | pmac->cipher_idx = cipher; | |
130 | pmac->buflen = 0; | |
131 | zeromem(pmac->block, sizeof(pmac->block)); | |
132 | zeromem(pmac->Li, sizeof(pmac->Li)); | |
133 | zeromem(pmac->checksum, sizeof(pmac->checksum)); | |
134 | err = CRYPT_OK; | |
135 | 135 | error: |
136 | 136 | #ifdef LTC_CLEAN_STACK |
137 | zeromem(L, pmac->block_len); | |
137 | zeromem(L, pmac->block_len); | |
138 | 138 | #endif |
139 | 139 | |
140 | XFREE(L); | |
140 | XFREE(L); | |
141 | 141 | |
142 | return err; | |
142 | return err; | |
143 | 143 | } |
144 | 144 | |
145 | 145 | #endif |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pmac_memory.c |
14 | PMAC implementation, process a block of memory, by Tom St Denis | |
14 | PMAC implementation, process a block of memory, by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PMAC |
27 | 27 | @param outlen [in/out] The max size and resulting size of the authentication tag |
28 | 28 | @return CRYPT_OK if successful |
29 | 29 | */ |
30 | int pmac_memory(int cipher, | |
30 | int pmac_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) |
45 | 45 | if (pmac == NULL) { |
46 | 46 | return CRYPT_MEM; |
47 | 47 | } |
48 | ||
48 | ||
49 | 49 | if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { |
50 | 50 | goto LBL_ERR; |
51 | 51 | } |
63 | 63 | #endif |
64 | 64 | |
65 | 65 | XFREE(pmac); |
66 | return err; | |
66 | return err; | |
67 | 67 | } |
68 | 68 | |
69 | 69 | #endif |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | #include <stdarg.h> |
12 | 12 | |
13 | /** | |
13 | /** | |
14 | 14 | @file pmac_memory_multi.c |
15 | PMAC implementation, process multiple blocks of memory, by Tom St Denis | |
15 | PMAC implementation, process multiple blocks of memory, by Tom St Denis | |
16 | 16 | */ |
17 | 17 | |
18 | 18 | #ifdef LTC_PMAC |
29 | 29 | @param ... tuples of (data,len) pairs to PMAC, terminated with a (NULL,x) (x=don't care) |
30 | 30 | @return CRYPT_OK if successful |
31 | 31 | */ |
32 | int pmac_memory_multi(int cipher, | |
32 | int pmac_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, ...) |
50 | 50 | if (pmac == NULL) { |
51 | 51 | return CRYPT_MEM; |
52 | 52 | } |
53 | ||
53 | ||
54 | 54 | if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { |
55 | 55 | goto LBL_ERR; |
56 | 56 | } |
57 | 57 | va_start(args, inlen); |
58 | curptr = in; | |
58 | curptr = in; | |
59 | 59 | curlen = inlen; |
60 | 60 | for (;;) { |
61 | 61 | /* process buf */ |
78 | 78 | #endif |
79 | 79 | XFREE(pmac); |
80 | 80 | va_end(args); |
81 | return err; | |
81 | return err; | |
82 | 82 | } |
83 | 83 | |
84 | 84 | #endif |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pmac_ntz.c |
14 | PMAC implementation, internal function, by Tom St Denis | |
14 | PMAC implementation, internal function, by Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | #ifdef LTC_PMAC |
61 | 61 | out[x] = xcbc->IV[x]; |
62 | 62 | } |
63 | 63 | *outlen = x; |
64 | ||
64 | ||
65 | 65 | #ifdef LTC_CLEAN_STACK |
66 | 66 | zeromem(xcbc, sizeof(*xcbc)); |
67 | 67 | #endif |
70 | 70 | if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { |
71 | 71 | goto done; |
72 | 72 | } |
73 | ||
73 | ||
74 | 74 | /* make the three keys */ |
75 | 75 | for (y = 0; y < 3; y++) { |
76 | 76 | for (x = 0; x < cipher_descriptor[cipher].block_length; x++) { |
79 | 79 | cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey); |
80 | 80 | } |
81 | 81 | } |
82 | ||
82 | ||
83 | 83 | /* setup K1 */ |
84 | 84 | err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key); |
85 | ||
85 | ||
86 | 86 | /* setup struct */ |
87 | 87 | zeromem(xcbc->IV, cipher_descriptor[cipher].block_length); |
88 | 88 | xcbc->blocksize = cipher_descriptor[cipher].block_length; |
90 | 90 | xcbc->buflen = 0; |
91 | 91 | done: |
92 | 92 | cipher_descriptor[cipher].done(skey); |
93 | if (skey != NULL) { | |
93 | if (skey != NULL) { | |
94 | 94 | #ifdef LTC_CLEAN_STACK |
95 | 95 | zeromem(skey, sizeof(*skey)); |
96 | 96 | #endif |
16 | 16 | |
17 | 17 | #ifdef LTC_XCBC |
18 | 18 | |
19 | /** XCBC-MAC a block of memory | |
19 | /** XCBC-MAC a block of memory | |
20 | 20 | @param cipher Index of cipher to use |
21 | 21 | @param key [in] Secret key |
22 | 22 | @param keylen Length of key in octets |
26 | 26 | @param outlen [in/out] Output size and final tag size |
27 | 27 | Return CRYPT_OK on success. |
28 | 28 | */ |
29 | int xcbc_memory(int cipher, | |
29 | int xcbc_memory(int cipher, | |
30 | 30 | const unsigned char *key, unsigned long keylen, |
31 | 31 | const unsigned char *in, unsigned long inlen, |
32 | 32 | unsigned char *out, unsigned long *outlen) |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | #include <stdarg.h> |
12 | 12 | |
13 | /** | |
13 | /** | |
14 | 14 | @file xcbc_memory_multi.c |
15 | 15 | XCBC support, process multiple blocks of memory, Tom St Denis |
16 | 16 | */ |
18 | 18 | #ifdef LTC_XCBC |
19 | 19 | |
20 | 20 | /** |
21 | XCBC multiple blocks of memory | |
21 | XCBC 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) |
29 | 29 | @param ... tuples of (data,len) pairs to XCBC, terminated with a (NULL,x) (x=don't care) |
30 | 30 | @return CRYPT_OK if successful |
31 | 31 | */ |
32 | int xcbc_memory_multi(int cipher, | |
32 | int xcbc_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(xcbc); |
81 | 81 | va_end(args); |
82 | return err; | |
82 | return err; | |
83 | 83 | } |
84 | 84 | |
85 | 85 | #endif |
14 | 14 | /** |
15 | 15 | @file rand_prime.c |
16 | 16 | Generate a random prime, Tom St Denis |
17 | */ | |
17 | */ | |
18 | 18 | |
19 | 19 | #define USE_BBS 1 |
20 | 20 | |
34 | 34 | } |
35 | 35 | |
36 | 36 | /* allow sizes between 2 and 512 bytes for a prime size */ |
37 | if (len < 2 || len > 512) { | |
37 | if (len < 2 || len > 512) { | |
38 | 38 | return CRYPT_INVALID_PRIME_SIZE; |
39 | 39 | } |
40 | ||
40 | ||
41 | 41 | /* valid PRNG? Better be! */ |
42 | 42 | if ((err = prng_is_valid(wprng)) != CRYPT_OK) { |
43 | return err; | |
43 | return err; | |
44 | 44 | } |
45 | 45 | |
46 | 46 | /* allocate buffer to work with */ |
59 | 59 | /* munge bits */ |
60 | 60 | buf[0] |= 0x80 | 0x40; |
61 | 61 | buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); |
62 | ||
62 | ||
63 | 63 | /* load value */ |
64 | 64 | if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { |
65 | 65 | XFREE(buf); |
80 | 80 | XFREE(buf); |
81 | 81 | return CRYPT_OK; |
82 | 82 | } |
83 | ||
83 | ||
84 | 84 | #endif /* LTC_NO_MATH */ |
85 | 85 | |
86 | 86 |
15 | 15 | */ |
16 | 16 | |
17 | 17 | /** |
18 | Find a cipher flexibly. First by name then if not present by block and key size | |
18 | Find a cipher flexibly. First by name then if not present by block and key size | |
19 | 19 | @param name The name of the cipher desired |
20 | 20 | @param blocklen The minimum length of the block cipher desired (octets) |
21 | 21 | @param keylen The minimum length of the key size desired (octets) |
15 | 15 | */ |
16 | 16 | |
17 | 17 | /** |
18 | Find a hash flexibly. First by name then if not present by digest size | |
18 | Find a hash flexibly. First by name then if not present by digest size | |
19 | 19 | @param name The name of the hash desired |
20 | 20 | @param digestlen The minimum length of the digest size (octets) |
21 | 21 | @return >= 0 if found, -1 if not present |
13 | 13 | /** |
14 | 14 | @file crypt_fsa.c |
15 | 15 | LibTomCrypt FULL SPEED AHEAD!, Tom St Denis |
16 | */ | |
16 | */ | |
17 | 17 | |
18 | 18 | /* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */ |
19 | 19 | int crypt_fsa(void *mp, ...) |
25 | 25 | if (mp != NULL) { |
26 | 26 | XMEMCPY(<c_mp, mp, sizeof(ltc_mp)); |
27 | 27 | } |
28 | ||
28 | ||
29 | 29 | while ((p = va_arg(args, void*)) != NULL) { |
30 | 30 | if (register_cipher(p) == -1) { |
31 | 31 | va_end(args); |
48 | 48 | } |
49 | 49 | |
50 | 50 | va_end(args); |
51 | return CRYPT_OK; | |
51 | return CRYPT_OK; | |
52 | 52 | } |
53 | 53 | |
54 | 54 |
11 | 11 | |
12 | 12 | /** |
13 | 13 | @file crypt_hash_descriptor.c |
14 | Stores the hash descriptor table, Tom St Denis | |
14 | Stores the hash descriptor table, Tom St Denis | |
15 | 15 | */ |
16 | 16 | |
17 | 17 | struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { |
12 | 12 | /** |
13 | 13 | @file crypt_hash_is_valid.c |
14 | 14 | Determine if hash is valid, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | /* |
18 | 18 | Test if a hash index is valid |
12 | 12 | /** |
13 | 13 | @file crypt_prng_descriptor.c |
14 | 14 | Stores the PRNG descriptors, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { |
17 | 17 | { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } |
18 | 18 | }; |
13 | 13 | @file crypt_register_prng.c |
14 | 14 | Register a PRNG, Tom St Denis |
15 | 15 | */ |
16 | ||
16 | ||
17 | 17 | /** |
18 | 18 | Register a PRNG with the descriptor table |
19 | 19 | @param prng The PRNG you wish to register |
20 | 20 | Initialize a CBC context |
21 | 21 | @param cipher The index of the cipher desired |
22 | 22 | @param IV The initial vector |
23 | @param key The secret key | |
23 | @param key The secret key | |
24 | 24 | @param keylen The length of the secret key (octets) |
25 | 25 | @param num_rounds Number of rounds in the cipher desired (0 for default) |
26 | 26 | @param cbc The CBC state to initialize |
27 | 27 | @return CRYPT_OK if successful |
28 | 28 | */ |
29 | int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, | |
29 | int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, | |
30 | 30 | int keylen, int num_rounds, symmetric_CBC *cbc) |
31 | 31 | { |
32 | 32 | int x, err; |
33 | ||
33 | ||
34 | 34 | LTC_ARGCHK(IV != NULL); |
35 | 35 | LTC_ARGCHK(key != NULL); |
36 | 36 | LTC_ARGCHK(cbc != NULL); |
51 | 51 | } |
52 | 52 | cfb->pad[cfb->padlen] = *ct; |
53 | 53 | *pt = *ct ^ cfb->IV[cfb->padlen]; |
54 | ++pt; | |
54 | ++pt; | |
55 | 55 | ++ct; |
56 | 56 | ++(cfb->padlen); |
57 | 57 | } |
50 | 50 | cfb->padlen = 0; |
51 | 51 | } |
52 | 52 | cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); |
53 | ++pt; | |
53 | ++pt; | |
54 | 54 | ++ct; |
55 | 55 | ++(cfb->padlen); |
56 | 56 | } |
12 | 12 | /** |
13 | 13 | @file cfb_setiv.c |
14 | 14 | CFB implementation, set IV, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_CFB_MODE |
18 | 18 | |
26 | 26 | int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb) |
27 | 27 | { |
28 | 28 | int err; |
29 | ||
29 | ||
30 | 30 | LTC_ARGCHK(IV != NULL); |
31 | 31 | LTC_ARGCHK(cfb != NULL); |
32 | 32 | |
33 | 33 | if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { |
34 | 34 | return err; |
35 | 35 | } |
36 | ||
36 | ||
37 | 37 | if (len != (unsigned long)cfb->blocklen) { |
38 | 38 | return CRYPT_INVALID_ARG; |
39 | 39 | } |
40 | ||
40 | ||
41 | 41 | /* force next block */ |
42 | 42 | cfb->padlen = 0; |
43 | 43 | return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); |
44 | 44 | } |
45 | 45 | |
46 | #endif | |
46 | #endif | |
47 | 47 | |
48 | 48 | |
49 | 49 | /* $Source$ */ |
21 | 21 | Initialize a CFB context |
22 | 22 | @param cipher The index of the cipher desired |
23 | 23 | @param IV The initial vector |
24 | @param key The secret key | |
24 | @param key The secret key | |
25 | 25 | @param keylen The length of the secret key (octets) |
26 | 26 | @param num_rounds Number of rounds in the cipher desired (0 for default) |
27 | 27 | @param cfb The CFB state to initialize |
28 | 28 | @return CRYPT_OK if successful |
29 | 29 | */ |
30 | int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, | |
30 | int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, | |
31 | 31 | int keylen, int num_rounds, symmetric_CFB *cfb) |
32 | 32 | { |
33 | 33 | int x, err; |
39 | 39 | if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { |
40 | 40 | return err; |
41 | 41 | } |
42 | ||
42 | ||
43 | 43 | |
44 | 44 | /* copy data */ |
45 | 45 | cfb->cipher = cipher; |
13 | 13 | @file ctr_setiv.c |
14 | 14 | CTR implementation, set IV, Tom St Denis |
15 | 15 | */ |
16 | ||
16 | ||
17 | 17 | #ifdef LTC_CTR_MODE |
18 | 18 | |
19 | 19 | /** |
26 | 26 | int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) |
27 | 27 | { |
28 | 28 | int err; |
29 | ||
29 | ||
30 | 30 | LTC_ARGCHK(IV != NULL); |
31 | 31 | LTC_ARGCHK(ctr != NULL); |
32 | 32 | |
34 | 34 | if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { |
35 | 35 | return err; |
36 | 36 | } |
37 | ||
37 | ||
38 | 38 | if (len != (unsigned long)ctr->blocklen) { |
39 | 39 | return CRYPT_INVALID_ARG; |
40 | 40 | } |
41 | 41 | |
42 | 42 | /* set IV */ |
43 | 43 | XMEMCPY(ctr->ctr, IV, len); |
44 | ||
44 | ||
45 | 45 | /* force next block */ |
46 | 46 | ctr->padlen = 0; |
47 | 47 | return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); |
48 | 48 | } |
49 | 49 | |
50 | #endif | |
50 | #endif | |
51 | 51 | |
52 | 52 | |
53 | 53 | /* $Source$ */ |
21 | 21 | Initialize a CTR context |
22 | 22 | @param cipher The index of the cipher desired |
23 | 23 | @param IV The initial vector |
24 | @param key The secret key | |
24 | @param key The secret key | |
25 | 25 | @param keylen The length of the secret key (octets) |
26 | 26 | @param num_rounds Number of rounds in the cipher desired (0 for default) |
27 | 27 | @param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN) |
28 | 28 | @param ctr The CTR state to initialize |
29 | 29 | @return CRYPT_OK if successful |
30 | 30 | */ |
31 | int ctr_start( int cipher, | |
32 | const unsigned char *IV, | |
33 | const unsigned char *key, int keylen, | |
31 | int ctr_start( int cipher, | |
32 | const unsigned char *IV, | |
33 | const unsigned char *key, int keylen, | |
34 | 34 | int num_rounds, int ctr_mode, |
35 | 35 | symmetric_CTR *ctr) |
36 | 36 | { |
90 | 90 | } |
91 | 91 | } |
92 | 92 | |
93 | return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); | |
93 | return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); | |
94 | 94 | } |
95 | 95 | |
96 | 96 | #endif |
20 | 20 | /** |
21 | 21 | Initialize a ECB context |
22 | 22 | @param cipher The index of the cipher desired |
23 | @param key The secret key | |
23 | @param key The secret key | |
24 | 24 | @param keylen The length of the secret key (octets) |
25 | 25 | @param num_rounds Number of rounds in the cipher desired (0 for default) |
26 | 26 | @param ecb The ECB state to initialize |
33 | 33 | if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { |
34 | 34 | return err; |
35 | 35 | } |
36 | ||
36 | ||
37 | 37 | /* is blocklen/padlen valid? */ |
38 | 38 | if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) || |
39 | 39 | ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) { |
40 | 40 | return CRYPT_INVALID_ARG; |
41 | 41 | } |
42 | ||
42 | ||
43 | 43 | while (len-- > 0) { |
44 | 44 | if (ofb->padlen == ofb->blocklen) { |
45 | 45 | if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) { |
43 | 43 | return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); |
44 | 44 | } |
45 | 45 | |
46 | #endif | |
46 | #endif | |
47 | 47 | |
48 | 48 | |
49 | 49 | /* $Source$ */ |
21 | 21 | Initialize a OFB context |
22 | 22 | @param cipher The index of the cipher desired |
23 | 23 | @param IV The initial vector |
24 | @param key The secret key | |
24 | @param key The secret key | |
25 | 25 | @param keylen The length of the secret key (octets) |
26 | 26 | @param num_rounds Number of rounds in the cipher desired (0 for default) |
27 | 27 | @param ofb The OFB state to initialize |
28 | 28 | @return CRYPT_OK if successful |
29 | 29 | */ |
30 | int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, | |
30 | int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, | |
31 | 31 | int keylen, int num_rounds, symmetric_OFB *ofb) |
32 | 32 | { |
33 | 33 | int x, err; |
44 | 44 | return CRYPT_INVALID_PACKET; |
45 | 45 | } |
46 | 46 | |
47 | /* offset in the data */ | |
48 | x = 1; | |
47 | /* offset in the data */ | |
48 | x = 1; | |
49 | 49 | |
50 | 50 | /* get the length of the data */ |
51 | 51 | if (in[x] & 0x80) { |
66 | 66 | /* short format */ |
67 | 67 | dlen = in[x++] & 0x7F; |
68 | 68 | } |
69 | ||
69 | ||
70 | 70 | /* is the data len too long or too short? */ |
71 | 71 | if ((dlen == 0) || (dlen + x > inlen)) { |
72 | 72 | return CRYPT_INVALID_PACKET; |
46 | 46 | return CRYPT_INVALID_PACKET; |
47 | 47 | } |
48 | 48 | |
49 | /* offset in the data */ | |
50 | x = 1; | |
49 | /* offset in the data */ | |
50 | x = 1; | |
51 | 51 | |
52 | 52 | /* get the length of the data */ |
53 | 53 | if (in[x] & 0x80) { |
16 | 16 | |
17 | 17 | #ifdef LTC_DER |
18 | 18 | /** |
19 | Gets length of DER encoding of BIT STRING | |
19 | Gets length of DER encoding of BIT STRING | |
20 | 20 | @param nbits The number of bits in the string to encode |
21 | 21 | @param outlen [out] The length of the DER encoding for the given string |
22 | 22 | @return CRYPT_OK if successful |
28 | 28 | |
29 | 29 | /* get the number of the bytes */ |
30 | 30 | nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; |
31 | ||
31 | ||
32 | 32 | if (nbytes < 128) { |
33 | 33 | /* 03 LL PP DD DD DD ... */ |
34 | 34 | *outlen = 2 + nbytes; |
29 | 29 | { |
30 | 30 | LTC_ARGCHK(in != NULL); |
31 | 31 | LTC_ARGCHK(out != NULL); |
32 | ||
32 | ||
33 | 33 | if (inlen < 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { |
34 | 34 | return CRYPT_INVALID_ARG; |
35 | 35 | } |
36 | ||
36 | ||
37 | 37 | *out = (in[2]==0xFF) ? 1 : 0; |
38 | ||
38 | ||
39 | 39 | return CRYPT_OK; |
40 | 40 | } |
41 | 41 |
24 | 24 | @param outlen [in/out] The max size and resulting size of the DER BOOLEAN |
25 | 25 | @return CRYPT_OK if successful |
26 | 26 | */ |
27 | int der_encode_boolean(int in, | |
27 | int der_encode_boolean(int in, | |
28 | 28 | unsigned char *out, unsigned long *outlen) |
29 | 29 | { |
30 | 30 | LTC_ARGCHK(outlen != NULL); |
31 | 31 | LTC_ARGCHK(out != NULL); |
32 | ||
32 | ||
33 | 33 | if (*outlen < 3) { |
34 | 34 | *outlen = 3; |
35 | 35 | return CRYPT_BUFFER_OVERFLOW; |
36 | 36 | } |
37 | ||
37 | ||
38 | 38 | *outlen = 3; |
39 | 39 | out[0] = 0x01; |
40 | 40 | out[1] = 0x01; |
41 | 41 | out[2] = in ? 0xFF : 0x00; |
42 | ||
42 | ||
43 | 43 | return CRYPT_OK; |
44 | 44 | } |
45 | 45 |
16 | 16 | |
17 | 17 | #ifdef LTC_DER |
18 | 18 | /** |
19 | Gets length of DER encoding of a BOOLEAN | |
19 | Gets length of DER encoding of a BOOLEAN | |
20 | 20 | @param outlen [out] The length of the DER encoding |
21 | 21 | @return CRYPT_OK if successful |
22 | 22 | */ |
36 | 36 | |
37 | 37 | /* get the size */ |
38 | 38 | if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { |
39 | return err; | |
39 | return err; | |
40 | 40 | } |
41 | 41 | |
42 | 42 | /* too big? */ |
20 | 20 | int code, value; |
21 | 21 | } ia5_table[] = { |
22 | 22 | { '\0', 0 }, |
23 | { '\a', 7 }, | |
24 | { '\b', 8 }, | |
25 | { '\t', 9 }, | |
26 | { '\n', 10 }, | |
27 | { '\f', 12 }, | |
28 | { '\r', 13 }, | |
29 | { ' ', 32 }, | |
30 | { '!', 33 }, | |
31 | { '"', 34 }, | |
32 | { '#', 35 }, | |
33 | { '$', 36 }, | |
34 | { '%', 37 }, | |
35 | { '&', 38 }, | |
36 | { '\'', 39 }, | |
37 | { '(', 40 }, | |
38 | { ')', 41 }, | |
39 | { '*', 42 }, | |
40 | { '+', 43 }, | |
41 | { ',', 44 }, | |
42 | { '-', 45 }, | |
43 | { '.', 46 }, | |
44 | { '/', 47 }, | |
45 | { '0', 48 }, | |
46 | { '1', 49 }, | |
47 | { '2', 50 }, | |
48 | { '3', 51 }, | |
49 | { '4', 52 }, | |
50 | { '5', 53 }, | |
51 | { '6', 54 }, | |
52 | { '7', 55 }, | |
53 | { '8', 56 }, | |
54 | { '9', 57 }, | |
55 | { ':', 58 }, | |
56 | { ';', 59 }, | |
57 | { '<', 60 }, | |
58 | { '=', 61 }, | |
59 | { '>', 62 }, | |
60 | { '?', 63 }, | |
61 | { '@', 64 }, | |
62 | { 'A', 65 }, | |
63 | { 'B', 66 }, | |
64 | { 'C', 67 }, | |
65 | { 'D', 68 }, | |
66 | { 'E', 69 }, | |
67 | { 'F', 70 }, | |
68 | { 'G', 71 }, | |
69 | { 'H', 72 }, | |
70 | { 'I', 73 }, | |
71 | { 'J', 74 }, | |
72 | { 'K', 75 }, | |
73 | { 'L', 76 }, | |
74 | { 'M', 77 }, | |
75 | { 'N', 78 }, | |
76 | { 'O', 79 }, | |
77 | { 'P', 80 }, | |
78 | { 'Q', 81 }, | |
79 | { 'R', 82 }, | |
80 | { 'S', 83 }, | |
81 | { 'T', 84 }, | |
82 | { 'U', 85 }, | |
83 | { 'V', 86 }, | |
84 | { 'W', 87 }, | |
85 | { 'X', 88 }, | |
86 | { 'Y', 89 }, | |
87 | { 'Z', 90 }, | |
88 | { '[', 91 }, | |
89 | { '\\', 92 }, | |
90 | { ']', 93 }, | |
91 | { '^', 94 }, | |
92 | { '_', 95 }, | |
93 | { '`', 96 }, | |
94 | { 'a', 97 }, | |
95 | { 'b', 98 }, | |
96 | { 'c', 99 }, | |
97 | { 'd', 100 }, | |
98 | { 'e', 101 }, | |
99 | { 'f', 102 }, | |
100 | { 'g', 103 }, | |
101 | { 'h', 104 }, | |
102 | { 'i', 105 }, | |
103 | { 'j', 106 }, | |
104 | { 'k', 107 }, | |
105 | { 'l', 108 }, | |
106 | { 'm', 109 }, | |
107 | { 'n', 110 }, | |
108 | { 'o', 111 }, | |
109 | { 'p', 112 }, | |
110 | { 'q', 113 }, | |
111 | { 'r', 114 }, | |
112 | { 's', 115 }, | |
113 | { 't', 116 }, | |
114 | { 'u', 117 }, | |
115 | { 'v', 118 }, | |
116 | { 'w', 119 }, | |
117 | { 'x', 120 }, | |
118 | { 'y', 121 }, | |
119 | { 'z', 122 }, | |
120 | { '{', 123 }, | |
121 | { '|', 124 }, | |
122 | { '}', 125 }, | |
23 | { '\a', 7 }, | |
24 | { '\b', 8 }, | |
25 | { '\t', 9 }, | |
26 | { '\n', 10 }, | |
27 | { '\f', 12 }, | |
28 | { '\r', 13 }, | |
29 | { ' ', 32 }, | |
30 | { '!', 33 }, | |
31 | { '"', 34 }, | |
32 | { '#', 35 }, | |
33 | { '$', 36 }, | |
34 | { '%', 37 }, | |
35 | { '&', 38 }, | |
36 | { '\'', 39 }, | |
37 | { '(', 40 }, | |
38 | { ')', 41 }, | |
39 | { '*', 42 }, | |
40 | { '+', 43 }, | |
41 | { ',', 44 }, | |
42 | { '-', 45 }, | |
43 | { '.', 46 }, | |
44 | { '/', 47 }, | |
45 | { '0', 48 }, | |
46 | { '1', 49 }, | |
47 | { '2', 50 }, | |
48 | { '3', 51 }, | |
49 | { '4', 52 }, | |
50 | { '5', 53 }, | |
51 | { '6', 54 }, | |
52 | { '7', 55 }, | |
53 | { '8', 56 }, | |
54 | { '9', 57 }, | |
55 | { ':', 58 }, | |
56 | { ';', 59 }, | |
57 | { '<', 60 }, | |
58 | { '=', 61 }, | |
59 | { '>', 62 }, | |
60 | { '?', 63 }, | |
61 | { '@', 64 }, | |
62 | { 'A', 65 }, | |
63 | { 'B', 66 }, | |
64 | { 'C', 67 }, | |
65 | { 'D', 68 }, | |
66 | { 'E', 69 }, | |
67 | { 'F', 70 }, | |
68 | { 'G', 71 }, | |
69 | { 'H', 72 }, | |
70 | { 'I', 73 }, | |
71 | { 'J', 74 }, | |
72 | { 'K', 75 }, | |
73 | { 'L', 76 }, | |
74 | { 'M', 77 }, | |
75 | { 'N', 78 }, | |
76 | { 'O', 79 }, | |
77 | { 'P', 80 }, | |
78 | { 'Q', 81 }, | |
79 | { 'R', 82 }, | |
80 | { 'S', 83 }, | |
81 | { 'T', 84 }, | |
82 | { 'U', 85 }, | |
83 | { 'V', 86 }, | |
84 | { 'W', 87 }, | |
85 | { 'X', 88 }, | |
86 | { 'Y', 89 }, | |
87 | { 'Z', 90 }, | |
88 | { '[', 91 }, | |
89 | { '\\', 92 }, | |
90 | { ']', 93 }, | |
91 | { '^', 94 }, | |
92 | { '_', 95 }, | |
93 | { '`', 96 }, | |
94 | { 'a', 97 }, | |
95 | { 'b', 98 }, | |
96 | { 'c', 99 }, | |
97 | { 'd', 100 }, | |
98 | { 'e', 101 }, | |
99 | { 'f', 102 }, | |
100 | { 'g', 103 }, | |
101 | { 'h', 104 }, | |
102 | { 'i', 105 }, | |
103 | { 'j', 106 }, | |
104 | { 'k', 107 }, | |
105 | { 'l', 108 }, | |
106 | { 'm', 109 }, | |
107 | { 'n', 110 }, | |
108 | { 'o', 111 }, | |
109 | { 'p', 112 }, | |
110 | { 'q', 113 }, | |
111 | { 'r', 114 }, | |
112 | { 's', 115 }, | |
113 | { 't', 116 }, | |
114 | { 'u', 117 }, | |
115 | { 'v', 118 }, | |
116 | { 'w', 119 }, | |
117 | { 'x', 120 }, | |
118 | { 'y', 121 }, | |
119 | { 'z', 122 }, | |
120 | { '{', 123 }, | |
121 | { '|', 124 }, | |
122 | { '}', 125 }, | |
123 | 123 | { '~', 126 } |
124 | 124 | }; |
125 | 125 | |
144 | 144 | } |
145 | 145 | return -1; |
146 | 146 | } |
147 | ||
147 | ||
148 | 148 | /** |
149 | Gets length of DER encoding of IA5 STRING | |
150 | @param octets The values you want to encode | |
149 | Gets length of DER encoding of IA5 STRING | |
150 | @param octets The values you want to encode | |
151 | 151 | @param noctets The number of octets in the string to encode |
152 | 152 | @param outlen [out] The length of the DER encoding for the given string |
153 | 153 | @return CRYPT_OK if successful |
53 | 53 | if (x + z > inlen) { |
54 | 54 | return CRYPT_INVALID_PACKET; |
55 | 55 | } |
56 | ||
56 | ||
57 | 57 | /* no so read it */ |
58 | 58 | if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { |
59 | 59 | return err; |
61 | 61 | } else { |
62 | 62 | /* long form */ |
63 | 63 | z &= 0x7F; |
64 | ||
64 | ||
65 | 65 | /* will number of length bytes overflow? (or > 4) */ |
66 | 66 | if (((x + z) > inlen) || (z > 4) || (z == 0)) { |
67 | 67 | return CRYPT_INVALID_PACKET; |
96 | 96 | return CRYPT_MEM; |
97 | 97 | } |
98 | 98 | mp_clear(tmp); |
99 | } | |
99 | } | |
100 | 100 | |
101 | 101 | return CRYPT_OK; |
102 | 102 |
26 | 26 | @return CRYPT_OK if successful |
27 | 27 | */ |
28 | 28 | int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) |
29 | { | |
29 | { | |
30 | 30 | unsigned long tmplen, y; |
31 | 31 | int err, leading_zero; |
32 | 32 | |
96 | 96 | } |
97 | 97 | } else if (mp_iszero(num) != LTC_MP_YES) { |
98 | 98 | void *tmp; |
99 | ||
99 | ||
100 | 100 | /* negative */ |
101 | 101 | if (mp_init(&tmp) != CRYPT_OK) { |
102 | 102 | return CRYPT_MEM; |
118 | 118 | } |
119 | 119 | |
120 | 120 | /* we good */ |
121 | *outlen = tmplen; | |
121 | *outlen = tmplen; | |
122 | 122 | return CRYPT_OK; |
123 | 123 | } |
124 | 124 |
47 | 47 | if ((in[x++] & 0x1F) != 0x06) { |
48 | 48 | return CRYPT_INVALID_PACKET; |
49 | 49 | } |
50 | ||
50 | ||
51 | 51 | /* get the length */ |
52 | 52 | if (in[x] < 128) { |
53 | len = in[x++]; | |
53 | len = in[x++]; | |
54 | 54 | } else { |
55 | if (in[x] < 0x81 || in[x] > 0x82) { | |
56 | return CRYPT_INVALID_PACKET; | |
57 | } | |
58 | y = in[x++] & 0x7F; | |
59 | len = 0; | |
60 | while (y--) { | |
61 | len = (len << 8) | (unsigned long)in[x++]; | |
62 | } | |
55 | if (in[x] < 0x81 || in[x] > 0x82) { | |
56 | return CRYPT_INVALID_PACKET; | |
57 | } | |
58 | y = in[x++] & 0x7F; | |
59 | len = 0; | |
60 | while (y--) { | |
61 | len = (len << 8) | (unsigned long)in[x++]; | |
62 | } | |
63 | 63 | } |
64 | 64 | |
65 | 65 | if (len < 1 || (len + x) > inlen) { |
70 | 70 | y = 0; |
71 | 71 | t = 0; |
72 | 72 | while (len--) { |
73 | t = (t << 7) | (in[x] & 0x7F); | |
74 | if (!(in[x++] & 0x80)) { | |
75 | /* store t */ | |
76 | if (y >= *outlen) { | |
77 | return CRYPT_BUFFER_OVERFLOW; | |
78 | } | |
79 | if (y == 0) { | |
80 | words[0] = t / 40; | |
81 | words[1] = t % 40; | |
82 | y = 2; | |
83 | } else { | |
84 | words[y++] = t; | |
73 | t = (t << 7) | (in[x] & 0x7F); | |
74 | if (!(in[x++] & 0x80)) { | |
75 | /* store t */ | |
76 | if (y >= *outlen) { | |
77 | return CRYPT_BUFFER_OVERFLOW; | |
78 | } | |
79 | if (y == 0) { | |
80 | words[0] = t / 40; | |
81 | words[1] = t % 40; | |
82 | y = 2; | |
83 | } else { | |
84 | words[y++] = t; | |
85 | } | |
86 | t = 0; | |
85 | 87 | } |
86 | t = 0; | |
87 | } | |
88 | 88 | } |
89 | ||
89 | ||
90 | 90 | *outlen = y; |
91 | 91 | return CRYPT_OK; |
92 | 92 | } |
54 | 54 | } |
55 | 55 | |
56 | 56 | /* store header + length */ |
57 | x = 0; | |
57 | x = 0; | |
58 | 58 | out[x++] = 0x06; |
59 | 59 | if (z < 128) { |
60 | 60 | out[x++] = (unsigned char)z; |
70 | 70 | } |
71 | 71 | |
72 | 72 | /* store first byte */ |
73 | wordbuf = words[0] * 40 + words[1]; | |
74 | for (i = 1; i < nwords; i++) { | |
75 | /* store 7 bit words in little endian */ | |
76 | t = wordbuf & 0xFFFFFFFF; | |
77 | if (t) { | |
78 | y = x; | |
79 | mask = 0; | |
80 | while (t) { | |
81 | out[x++] = (unsigned char)((t & 0x7F) | mask); | |
82 | t >>= 7; | |
83 | mask |= 0x80; /* upper bit is set on all but the last byte */ | |
84 | } | |
85 | /* now swap bytes y...x-1 */ | |
86 | z = x - 1; | |
87 | while (y < z) { | |
88 | t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; | |
89 | ++y; | |
90 | --z; | |
91 | } | |
92 | } else { | |
93 | /* zero word */ | |
94 | out[x++] = 0x00; | |
95 | } | |
96 | ||
97 | if (i < nwords - 1) { | |
98 | wordbuf = words[i + 1]; | |
99 | } | |
73 | wordbuf = words[0] * 40 + words[1]; | |
74 | for (i = 1; i < nwords; i++) { | |
75 | /* store 7 bit words in little endian */ | |
76 | t = wordbuf & 0xFFFFFFFF; | |
77 | if (t) { | |
78 | y = x; | |
79 | mask = 0; | |
80 | while (t) { | |
81 | out[x++] = (unsigned char)((t & 0x7F) | mask); | |
82 | t >>= 7; | |
83 | mask |= 0x80; /* upper bit is set on all but the last byte */ | |
84 | } | |
85 | /* now swap bytes y...x-1 */ | |
86 | z = x - 1; | |
87 | while (y < z) { | |
88 | t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; | |
89 | ++y; | |
90 | --z; | |
91 | } | |
92 | } else { | |
93 | /* zero word */ | |
94 | out[x++] = 0x00; | |
95 | } | |
96 | ||
97 | if (i < nwords - 1) { | |
98 | wordbuf = words[i + 1]; | |
99 | } | |
100 | 100 | } |
101 | 101 | |
102 | 102 | *outlen = x; |
31 | 31 | |
32 | 32 | /** |
33 | 33 | Gets length of DER encoding of Object Identifier |
34 | @param nwords The number of OID words | |
34 | @param nwords The number of OID words | |
35 | 35 | @param words The actual OID words to get the size of |
36 | 36 | @param outlen [out] The length of the DER encoding for the given string |
37 | 37 | @return CRYPT_OK if successful |
38 | 38 | */ |
39 | 39 | int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) |
40 | 40 | { |
41 | unsigned long y, z, t, wordbuf; | |
41 | unsigned long y, z, t, wordbuf; | |
42 | 42 | |
43 | 43 | LTC_ARGCHK(words != NULL); |
44 | 44 | LTC_ARGCHK(outlen != NULL); |
37 | 37 | |
38 | 38 | /* get the size */ |
39 | 39 | if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { |
40 | return err; | |
40 | return err; | |
41 | 41 | } |
42 | 42 | |
43 | 43 | /* too big? */ |
16 | 16 | |
17 | 17 | #ifdef LTC_DER |
18 | 18 | /** |
19 | Gets length of DER encoding of OCTET STRING | |
19 | Gets length of DER encoding of OCTET STRING | |
20 | 20 | @param noctets The number of octets in the string to encode |
21 | 21 | @param outlen [out] The length of the DER encoding for the given string |
22 | 22 | @return CRYPT_OK if successful |
36 | 36 | |
37 | 37 | /* get the size */ |
38 | 38 | if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { |
39 | return err; | |
39 | return err; | |
40 | 40 | } |
41 | 41 | |
42 | 42 | /* too big? */ |
19 | 19 | static const struct { |
20 | 20 | int code, value; |
21 | 21 | } printable_table[] = { |
22 | { ' ', 32 }, | |
23 | { '\'', 39 }, | |
24 | { '(', 40 }, | |
25 | { ')', 41 }, | |
26 | { '+', 43 }, | |
27 | { ',', 44 }, | |
28 | { '-', 45 }, | |
29 | { '.', 46 }, | |
30 | { '/', 47 }, | |
31 | { '0', 48 }, | |
32 | { '1', 49 }, | |
33 | { '2', 50 }, | |
34 | { '3', 51 }, | |
35 | { '4', 52 }, | |
36 | { '5', 53 }, | |
37 | { '6', 54 }, | |
38 | { '7', 55 }, | |
39 | { '8', 56 }, | |
40 | { '9', 57 }, | |
41 | { ':', 58 }, | |
42 | { '=', 61 }, | |
43 | { '?', 63 }, | |
44 | { 'A', 65 }, | |
45 | { 'B', 66 }, | |
46 | { 'C', 67 }, | |
47 | { 'D', 68 }, | |
48 | { 'E', 69 }, | |
49 | { 'F', 70 }, | |
50 | { 'G', 71 }, | |
51 | { 'H', 72 }, | |
52 | { 'I', 73 }, | |
53 | { 'J', 74 }, | |
54 | { 'K', 75 }, | |
55 | { 'L', 76 }, | |
56 | { 'M', 77 }, | |
57 | { 'N', 78 }, | |
58 | { 'O', 79 }, | |
59 | { 'P', 80 }, | |
60 | { 'Q', 81 }, | |
61 | { 'R', 82 }, | |
62 | { 'S', 83 }, | |
63 | { 'T', 84 }, | |
64 | { 'U', 85 }, | |
65 | { 'V', 86 }, | |
66 | { 'W', 87 }, | |
67 | { 'X', 88 }, | |
68 | { 'Y', 89 }, | |
69 | { 'Z', 90 }, | |
70 | { 'a', 97 }, | |
71 | { 'b', 98 }, | |
72 | { 'c', 99 }, | |
73 | { 'd', 100 }, | |
74 | { 'e', 101 }, | |
75 | { 'f', 102 }, | |
76 | { 'g', 103 }, | |
77 | { 'h', 104 }, | |
78 | { 'i', 105 }, | |
79 | { 'j', 106 }, | |
80 | { 'k', 107 }, | |
81 | { 'l', 108 }, | |
82 | { 'm', 109 }, | |
83 | { 'n', 110 }, | |
84 | { 'o', 111 }, | |
85 | { 'p', 112 }, | |
86 | { 'q', 113 }, | |
87 | { 'r', 114 }, | |
88 | { 's', 115 }, | |
89 | { 't', 116 }, | |
90 | { 'u', 117 }, | |
91 | { 'v', 118 }, | |
92 | { 'w', 119 }, | |
93 | { 'x', 120 }, | |
94 | { 'y', 121 }, | |
95 | { 'z', 122 }, | |
22 | { ' ', 32 }, | |
23 | { '\'', 39 }, | |
24 | { '(', 40 }, | |
25 | { ')', 41 }, | |
26 | { '+', 43 }, | |
27 | { ',', 44 }, | |
28 | { '-', 45 }, | |
29 | { '.', 46 }, | |
30 | { '/', 47 }, | |
31 | { '0', 48 }, | |
32 | { '1', 49 }, | |
33 | { '2', 50 }, | |
34 | { '3', 51 }, | |
35 | { '4', 52 }, | |
36 | { '5', 53 }, | |
37 | { '6', 54 }, | |
38 | { '7', 55 }, | |
39 | { '8', 56 }, | |
40 | { '9', 57 }, | |
41 | { ':', 58 }, | |
42 | { '=', 61 }, | |
43 | { '?', 63 }, | |
44 | { 'A', 65 }, | |
45 | { 'B', 66 }, | |
46 | { 'C', 67 }, | |
47 | { 'D', 68 }, | |
48 | { 'E', 69 }, | |
49 | { 'F', 70 }, | |
50 | { 'G', 71 }, | |
51 | { 'H', 72 }, | |
52 | { 'I', 73 }, | |
53 | { 'J', 74 }, | |
54 | { 'K', 75 }, | |
55 | { 'L', 76 }, | |
56 | { 'M', 77 }, | |
57 | { 'N', 78 }, | |
58 | { 'O', 79 }, | |
59 | { 'P', 80 }, | |
60 | { 'Q', 81 }, | |
61 | { 'R', 82 }, | |
62 | { 'S', 83 }, | |
63 | { 'T', 84 }, | |
64 | { 'U', 85 }, | |
65 | { 'V', 86 }, | |
66 | { 'W', 87 }, | |
67 | { 'X', 88 }, | |
68 | { 'Y', 89 }, | |
69 | { 'Z', 90 }, | |
70 | { 'a', 97 }, | |
71 | { 'b', 98 }, | |
72 | { 'c', 99 }, | |
73 | { 'd', 100 }, | |
74 | { 'e', 101 }, | |
75 | { 'f', 102 }, | |
76 | { 'g', 103 }, | |
77 | { 'h', 104 }, | |
78 | { 'i', 105 }, | |
79 | { 'j', 106 }, | |
80 | { 'k', 107 }, | |
81 | { 'l', 108 }, | |
82 | { 'm', 109 }, | |
83 | { 'n', 110 }, | |
84 | { 'o', 111 }, | |
85 | { 'p', 112 }, | |
86 | { 'q', 113 }, | |
87 | { 'r', 114 }, | |
88 | { 's', 115 }, | |
89 | { 't', 116 }, | |
90 | { 'u', 117 }, | |
91 | { 'v', 118 }, | |
92 | { 'w', 119 }, | |
93 | { 'x', 120 }, | |
94 | { 'y', 121 }, | |
95 | { 'z', 122 }, | |
96 | 96 | }; |
97 | 97 | |
98 | 98 | int der_printable_char_encode(int c) |
116 | 116 | } |
117 | 117 | return -1; |
118 | 118 | } |
119 | ||
119 | ||
120 | 120 | /** |
121 | Gets length of DER encoding of Printable STRING | |
122 | @param octets The values you want to encode | |
121 | Gets length of DER encoding of Printable STRING | |
122 | @param octets The values you want to encode | |
123 | 123 | @param noctets The number of octets in the string to encode |
124 | 124 | @param outlen [out] The length of the DER encoding for the given string |
125 | 125 | @return CRYPT_OK if successful |
19 | 19 | /** |
20 | 20 | Free memory allocated by der_decode_sequence_flexi() |
21 | 21 | @param in The list to free |
22 | */ | |
22 | */ | |
23 | 23 | void der_sequence_free(ltc_asn1_list *in) |
24 | 24 | { |
25 | 25 | ltc_asn1_list *l; |
26 | 26 | |
27 | 27 | if (!in) return; |
28 | ||
28 | ||
29 | 29 | /* walk to the start of the chain */ |
30 | 30 | while (in->prev != NULL || in->parent != NULL) { |
31 | 31 | if (in->parent != NULL) { |
34 | 34 | in = in->prev; |
35 | 35 | } |
36 | 36 | } |
37 | ||
37 | ||
38 | 38 | /* now walk the list and free stuff */ |
39 | 39 | while (in != NULL) { |
40 | 40 | /* is there a child? */ |
43 | 43 | in->child->parent = NULL; |
44 | 44 | der_sequence_free(in->child); |
45 | 45 | } |
46 | ||
47 | switch (in->type) { | |
46 | ||
47 | switch (in->type) { | |
48 | 48 | case LTC_ASN1_SET: |
49 | 49 | case LTC_ASN1_SETOF: |
50 | 50 | case LTC_ASN1_SEQUENCE: break; |
51 | 51 | case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; |
52 | 52 | default : if (in->data != NULL) { XFREE(in->data); } |
53 | 53 | } |
54 | ||
54 | ||
55 | 55 | /* move to next and free current */ |
56 | 56 | l = in->next; |
57 | 57 | XFREE(in); |
58 | 58 | in = l; |
59 | } | |
59 | } | |
60 | 60 | } |
61 | 61 | |
62 | 62 | #endif |
25 | 25 | @return CRYPT_OK if successful |
26 | 26 | */ |
27 | 27 | int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) |
28 | { | |
28 | { | |
29 | 29 | unsigned long len, x, y, z; |
30 | 30 | int err; |
31 | ||
31 | ||
32 | 32 | LTC_ARGCHK(out != NULL); |
33 | 33 | LTC_ARGCHK(outlen != NULL); |
34 | 34 | |
85 | 85 | |
86 | 86 | /* we good */ |
87 | 87 | *outlen = x; |
88 | ||
88 | ||
89 | 89 | return CRYPT_OK; |
90 | 90 | } |
91 | 91 |
17 | 17 | |
18 | 18 | #ifdef LTC_DER |
19 | 19 | /** |
20 | Gets length of DER encoding of num | |
21 | @param num The integer to get the size of | |
20 | Gets length of DER encoding of num | |
21 | @param num The integer 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 | */ |
38 | 38 | ++z; |
39 | 39 | y >>= 8; |
40 | 40 | } |
41 | ||
41 | ||
42 | 42 | /* handle zero */ |
43 | 43 | if (z == 0) { |
44 | 44 | z = 1; |
57 | 57 | len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; |
58 | 58 | |
59 | 59 | /* return length */ |
60 | *outlen = len; | |
61 | ||
60 | *outlen = len; | |
61 | ||
62 | 62 | return CRYPT_OK; |
63 | 63 | } |
64 | 64 |
27 | 27 | { '\v', 11 }, |
28 | 28 | { '\f', 12 }, |
29 | 29 | { '\r', 13 }, |
30 | { ' ', 32 }, | |
31 | { '!', 33 }, | |
32 | { '"', 34 }, | |
33 | { '%', 37 }, | |
34 | { '&', 38 }, | |
35 | { '\'', 39 }, | |
36 | { '(', 40 }, | |
37 | { ')', 41 }, | |
38 | { '+', 43 }, | |
39 | { ',', 44 }, | |
40 | { '-', 45 }, | |
41 | { '.', 46 }, | |
42 | { '/', 47 }, | |
43 | { '0', 48 }, | |
44 | { '1', 49 }, | |
45 | { '2', 50 }, | |
46 | { '3', 51 }, | |
47 | { '4', 52 }, | |
48 | { '5', 53 }, | |
49 | { '6', 54 }, | |
50 | { '7', 55 }, | |
51 | { '8', 56 }, | |
52 | { '9', 57 }, | |
53 | { ':', 58 }, | |
54 | { ';', 59 }, | |
55 | { '<', 60 }, | |
56 | { '=', 61 }, | |
57 | { '>', 62 }, | |
58 | { '?', 63 }, | |
59 | { '@', 64 }, | |
60 | { 'A', 65 }, | |
61 | { 'B', 66 }, | |
62 | { 'C', 67 }, | |
63 | { 'D', 68 }, | |
64 | { 'E', 69 }, | |
65 | { 'F', 70 }, | |
66 | { 'G', 71 }, | |
67 | { 'H', 72 }, | |
68 | { 'I', 73 }, | |
69 | { 'J', 74 }, | |
70 | { 'K', 75 }, | |
71 | { 'L', 76 }, | |
72 | { 'M', 77 }, | |
73 | { 'N', 78 }, | |
74 | { 'O', 79 }, | |
75 | { 'P', 80 }, | |
76 | { 'Q', 81 }, | |
77 | { 'R', 82 }, | |
78 | { 'S', 83 }, | |
79 | { 'T', 84 }, | |
80 | { 'U', 85 }, | |
81 | { 'V', 86 }, | |
82 | { 'W', 87 }, | |
83 | { 'X', 88 }, | |
84 | { 'Y', 89 }, | |
85 | { 'Z', 90 }, | |
86 | { '[', 91 }, | |
87 | { ']', 93 }, | |
88 | { '_', 95 }, | |
89 | { 'a', 97 }, | |
90 | { 'b', 98 }, | |
91 | { 'c', 99 }, | |
92 | { 'd', 100 }, | |
93 | { 'e', 101 }, | |
94 | { 'f', 102 }, | |
95 | { 'g', 103 }, | |
96 | { 'h', 104 }, | |
97 | { 'i', 105 }, | |
98 | { 'j', 106 }, | |
99 | { 'k', 107 }, | |
100 | { 'l', 108 }, | |
101 | { 'm', 109 }, | |
102 | { 'n', 110 }, | |
103 | { 'o', 111 }, | |
104 | { 'p', 112 }, | |
105 | { 'q', 113 }, | |
106 | { 'r', 114 }, | |
107 | { 's', 115 }, | |
108 | { 't', 116 }, | |
109 | { 'u', 117 }, | |
110 | { 'v', 118 }, | |
111 | { 'w', 119 }, | |
112 | { 'x', 120 }, | |
113 | { 'y', 121 }, | |
114 | { 'z', 122 }, | |
115 | { '|', 124 }, | |
116 | { ' ', 160 }, | |
117 | { 0xa1, 161 }, | |
118 | { 0xa2, 162 }, | |
119 | { 0xa3, 163 }, | |
120 | { '$', 164 }, | |
121 | { 0xa5, 165 }, | |
122 | { '#', 166 }, | |
123 | { 0xa7, 167 }, | |
124 | { 0xa4, 168 }, | |
125 | { 0xab, 171 }, | |
126 | { 0xb0, 176 }, | |
127 | { 0xb1, 177 }, | |
128 | { 0xb2, 178 }, | |
129 | { 0xb3, 179 }, | |
130 | { 0xd7, 180 }, | |
131 | { 0xb5, 181 }, | |
132 | { 0xb6, 182 }, | |
133 | { 0xb7, 183 }, | |
134 | { 0xf7, 184 }, | |
135 | { 0xbb, 187 }, | |
136 | { 0xbc, 188 }, | |
137 | { 0xbd, 189 }, | |
138 | { 0xbe, 190 }, | |
139 | { 0xbf, 191 }, | |
30 | { ' ', 32 }, | |
31 | { '!', 33 }, | |
32 | { '"', 34 }, | |
33 | { '%', 37 }, | |
34 | { '&', 38 }, | |
35 | { '\'', 39 }, | |
36 | { '(', 40 }, | |
37 | { ')', 41 }, | |
38 | { '+', 43 }, | |
39 | { ',', 44 }, | |
40 | { '-', 45 }, | |
41 | { '.', 46 }, | |
42 | { '/', 47 }, | |
43 | { '0', 48 }, | |
44 | { '1', 49 }, | |
45 | { '2', 50 }, | |
46 | { '3', 51 }, | |
47 | { '4', 52 }, | |
48 | { '5', 53 }, | |
49 | { '6', 54 }, | |
50 | { '7', 55 }, | |
51 | { '8', 56 }, | |
52 | { '9', 57 }, | |
53 | { ':', 58 }, | |
54 | { ';', 59 }, | |
55 | { '<', 60 }, | |
56 | { '=', 61 }, | |
57 | { '>', 62 }, | |
58 | { '?', 63 }, | |
59 | { '@', 64 }, | |
60 | { 'A', 65 }, | |
61 | { 'B', 66 }, | |
62 | { 'C', 67 }, | |
63 | { 'D', 68 }, | |
64 | { 'E', 69 }, | |
65 | { 'F', 70 }, | |
66 | { 'G', 71 }, | |
67 | { 'H', 72 }, | |
68 | { 'I', 73 }, | |
69 | { 'J', 74 }, | |
70 | { 'K', 75 }, | |
71 | { 'L', 76 }, | |
72 | { 'M', 77 }, | |
73 | { 'N', 78 }, | |
74 | { 'O', 79 }, | |
75 | { 'P', 80 }, | |
76 | { 'Q', 81 }, | |
77 | { 'R', 82 }, | |
78 | { 'S', 83 }, | |
79 | { 'T', 84 }, | |
80 | { 'U', 85 }, | |
81 | { 'V', 86 }, | |
82 | { 'W', 87 }, | |
83 | { 'X', 88 }, | |
84 | { 'Y', 89 }, | |
85 | { 'Z', 90 }, | |
86 | { '[', 91 }, | |
87 | { ']', 93 }, | |
88 | { '_', 95 }, | |
89 | { 'a', 97 }, | |
90 | { 'b', 98 }, | |
91 | { 'c', 99 }, | |
92 | { 'd', 100 }, | |
93 | { 'e', 101 }, | |
94 | { 'f', 102 }, | |
95 | { 'g', 103 }, | |
96 | { 'h', 104 }, | |
97 | { 'i', 105 }, | |
98 | { 'j', 106 }, | |
99 | { 'k', 107 }, | |
100 | { 'l', 108 }, | |
101 | { 'm', 109 }, | |
102 | { 'n', 110 }, | |
103 | { 'o', 111 }, | |
104 | { 'p', 112 }, | |
105 | { 'q', 113 }, | |
106 | { 'r', 114 }, | |
107 | { 's', 115 }, | |
108 | { 't', 116 }, | |
109 | { 'u', 117 }, | |
110 | { 'v', 118 }, | |
111 | { 'w', 119 }, | |
112 | { 'x', 120 }, | |
113 | { 'y', 121 }, | |
114 | { 'z', 122 }, | |
115 | { '|', 124 }, | |
116 | { ' ', 160 }, | |
117 | { 0xa1, 161 }, | |
118 | { 0xa2, 162 }, | |
119 | { 0xa3, 163 }, | |
120 | { '$', 164 }, | |
121 | { 0xa5, 165 }, | |
122 | { '#', 166 }, | |
123 | { 0xa7, 167 }, | |
124 | { 0xa4, 168 }, | |
125 | { 0xab, 171 }, | |
126 | { 0xb0, 176 }, | |
127 | { 0xb1, 177 }, | |
128 | { 0xb2, 178 }, | |
129 | { 0xb3, 179 }, | |
130 | { 0xd7, 180 }, | |
131 | { 0xb5, 181 }, | |
132 | { 0xb6, 182 }, | |
133 | { 0xb7, 183 }, | |
134 | { 0xf7, 184 }, | |
135 | { 0xbb, 187 }, | |
136 | { 0xbc, 188 }, | |
137 | { 0xbd, 189 }, | |
138 | { 0xbe, 190 }, | |
139 | { 0xbf, 191 }, | |
140 | 140 | }; |
141 | 141 | |
142 | 142 | int der_teletex_char_encode(int c) |
160 | 160 | } |
161 | 161 | return -1; |
162 | 162 | } |
163 | ||
163 | ||
164 | 164 | /** |
165 | Gets length of DER encoding of teletex STRING | |
166 | @param octets The values you want to encode | |
165 | Gets length of DER encoding of teletex STRING | |
166 | @param octets The values you want to encode | |
167 | 167 | @param noctets The number of octets in the string to encode |
168 | 168 | @param outlen [out] The length of the DER encoding for the given string |
169 | 169 | @return CRYPT_OK if successful |
72 | 72 | *inlen = 2 + x; |
73 | 73 | |
74 | 74 | |
75 | /* possible encodings are | |
75 | /* possible encodings are | |
76 | 76 | YYMMDDhhmmZ |
77 | 77 | YYMMDDhhmm+hh'mm' |
78 | 78 | YYMMDDhhmm-hh'mm' |
80 | 80 | YYMMDDhhmmss+hh'mm' |
81 | 81 | YYMMDDhhmmss-hh'mm' |
82 | 82 | |
83 | So let's do a trivial decode upto [including] mm | |
83 | So let's do a trivial decode upto [including] mm | |
84 | 84 | */ |
85 | 85 | |
86 | 86 | x = 0; |
72 | 72 | for (y = 0; x < inlen; ) { |
73 | 73 | /* get first byte */ |
74 | 74 | tmp = in[x++]; |
75 | ||
75 | ||
76 | 76 | /* count number of bytes */ |
77 | 77 | for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); |
78 | ||
78 | ||
79 | 79 | if (z > 4 || (x + (z - 1) > inlen)) { |
80 | 80 | return CRYPT_INVALID_PACKET; |
81 | 81 | } |
102 | 102 | |
103 | 103 | return CRYPT_OK; |
104 | 104 | } |
105 | ||
105 | ||
106 | 106 | #endif |
107 | 107 | |
108 | 108 | /* $Source$ */ |
12 | 12 | /** |
13 | 13 | @file dsa_decrypt_key.c |
14 | 14 | DSA Crypto, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_MDSA |
18 | 18 | |
26 | 26 | @return CRYPT_OK if successful |
27 | 27 | */ |
28 | 28 | int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, |
29 | unsigned char *out, unsigned long *outlen, | |
29 | unsigned char *out, unsigned long *outlen, | |
30 | 30 | dsa_key *key) |
31 | 31 | { |
32 | 32 | unsigned char *skey, *expt; |
44 | 44 | if (key->type != PK_PRIVATE) { |
45 | 45 | return CRYPT_PK_NOT_PRIVATE; |
46 | 46 | } |
47 | ||
47 | ||
48 | 48 | /* decode to find out hash */ |
49 | 49 | LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); |
50 | ||
50 | ||
51 | 51 | if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { |
52 | 52 | return err; |
53 | 53 | } |
54 | 54 | |
55 | hash = find_hash_oid(hashOID, decode[0].size); | |
55 | hash = find_hash_oid(hashOID, decode[0].size); | |
56 | 56 | if (hash_is_valid(hash) != CRYPT_OK) { |
57 | 57 | return CRYPT_INVALID_PACKET; |
58 | 58 | } |
59 | 59 | |
60 | 60 | /* we now have the hash! */ |
61 | ||
61 | ||
62 | 62 | if ((err = mp_init(&g_pub)) != CRYPT_OK) { |
63 | 63 | return err; |
64 | 64 | } |
76 | 76 | mp_clear(g_pub); |
77 | 77 | return CRYPT_MEM; |
78 | 78 | } |
79 | ||
79 | ||
80 | 80 | LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL); |
81 | 81 | LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); |
82 | 82 | |
124 | 124 | |
125 | 125 | XFREE(expt); |
126 | 126 | XFREE(skey); |
127 | ||
127 | ||
128 | 128 | mp_clear(g_pub); |
129 | 129 | |
130 | 130 | return err; |
12 | 12 | /** |
13 | 13 | @file dsa_encrypt_key.c |
14 | 14 | DSA Crypto, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_MDSA |
18 | 18 | |
23 | 23 | @param out [out] The destination for the ciphertext |
24 | 24 | @param outlen [in/out] The max size and resulting size of the ciphertext |
25 | 25 | @param prng An active PRNG state |
26 | @param wprng The index of the PRNG you wish to use | |
27 | @param hash The index of the hash you want to use | |
26 | @param wprng The index of the PRNG you wish to use | |
27 | @param hash The index of the hash you want to use | |
28 | 28 | @param key The DSA key you want to encrypt to |
29 | 29 | @return CRYPT_OK if successful |
30 | 30 | */ |
31 | 31 | int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, |
32 | unsigned char *out, unsigned long *outlen, | |
33 | prng_state *prng, int wprng, int hash, | |
32 | unsigned char *out, unsigned long *outlen, | |
33 | prng_state *prng, int wprng, int hash, | |
34 | 34 | dsa_key *key) |
35 | 35 | { |
36 | 36 | unsigned char *expt, *skey; |
60 | 60 | if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) { |
61 | 61 | return err; |
62 | 62 | } |
63 | ||
63 | ||
64 | 64 | expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); |
65 | 65 | skey = XMALLOC(MAXBLOCKSIZE); |
66 | 66 | if (expt == NULL || skey == NULL) { |
73 | 73 | mp_clear_multi(g_pub, g_priv, NULL); |
74 | 74 | return CRYPT_MEM; |
75 | 75 | } |
76 | ||
76 | ||
77 | 77 | /* make a random g_priv, g_pub = g^x pair */ |
78 | 78 | qbits = mp_count_bits(key->q); |
79 | 79 | do { |
87 | 87 | if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) { |
88 | 88 | goto LBL_ERR; |
89 | 89 | } |
90 | ||
90 | ||
91 | 91 | /* make random key */ |
92 | 92 | x = mp_unsigned_bin_size(key->p) + 1; |
93 | 93 | if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) { |
98 | 98 | if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) { |
99 | 99 | goto LBL_ERR; |
100 | 100 | } |
101 | ||
101 | ||
102 | 102 | /* Encrypt key */ |
103 | 103 | for (x = 0; x < inlen; x++) { |
104 | 104 | skey[x] ^= in[x]; |
119 | 119 | |
120 | 120 | XFREE(skey); |
121 | 121 | XFREE(expt); |
122 | ||
122 | ||
123 | 123 | mp_clear_multi(g_pub, g_priv, NULL); |
124 | 124 | return err; |
125 | 125 | } |
36 | 36 | /* init key */ |
37 | 37 | err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL); |
38 | 38 | if (err != CRYPT_OK) return err; |
39 | ||
39 | ||
40 | 40 | if ((err = mp_read_radix(key->p , p , radix)) != CRYPT_OK) { goto LBL_ERR; } |
41 | 41 | if ((err = mp_read_radix(key->q , q , radix)) != CRYPT_OK) { goto LBL_ERR; } |
42 | 42 | if ((err = mp_read_radix(key->g , g , radix)) != CRYPT_OK) { goto LBL_ERR; } |
12 | 12 | /** |
13 | 13 | @file dsa_shared_secret.c |
14 | 14 | DSA Crypto, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_MDSA |
18 | 18 | |
19 | 19 | /** |
20 | 20 | Create a DSA shared secret between two keys |
21 | 21 | @param private_key The private DSA key (the exponent) |
22 | @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt) | |
22 | @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt) | |
23 | 23 | @param public_key The public key |
24 | 24 | @param out [out] Destination of the shared secret |
25 | 25 | @param outlen [in/out] The max size and resulting size of the shared secret |
47 | 47 | mp_clear(res); |
48 | 48 | return err; |
49 | 49 | } |
50 | ||
50 | ||
51 | 51 | x = (unsigned long)mp_unsigned_bin_size(res); |
52 | 52 | if (*outlen < x) { |
53 | 53 | *outlen = x; |
88 | 88 | /* at this point we are out of tests ;-( */ |
89 | 89 | err = CRYPT_OK; |
90 | 90 | *stat = 1; |
91 | error: | |
91 | error: | |
92 | 92 | mp_clear_multi(tmp, tmp2, NULL); |
93 | 93 | return err; |
94 | 94 | } |
9 | 9 | */ |
10 | 10 | #include "tomcrypt.h" |
11 | 11 | |
12 | /** | |
12 | /** | |
13 | 13 | @file pkcs_1_os2ip.c |
14 | Octet to Integer OS2IP, Tom St Denis | |
14 | Octet to Integer OS2IP, Tom St Denis | |
15 | 15 | */ |
16 | 16 | #ifdef LTC_PKCS_1 |
17 | 17 |
12 | 12 | /** |
13 | 13 | @file rsa_free.c |
14 | 14 | Free an RSA key, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_MRSA |
18 | 18 |
87 | 87 | return CRYPT_INVALID_ARG; |
88 | 88 | } |
89 | 89 | |
90 | /* construct the SEQUENCE | |
90 | /* construct the SEQUENCE | |
91 | 91 | SEQUENCE { |
92 | 92 | SEQUENCE {hashoid OID |
93 | 93 | blah NULL |
94 | 94 | } |
95 | hash OCTET STRING | |
95 | hash OCTET STRING | |
96 | 96 | } |
97 | 97 | */ |
98 | 98 | LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); |
13 | 13 | @file fortuna.c |
14 | 14 | Fortuna PRNG, Tom St Denis |
15 | 15 | */ |
16 | ||
17 | /* Implementation of Fortuna by Tom St Denis | |
16 | ||
17 | /* Implementation of Fortuna by Tom St Denis | |
18 | 18 | |
19 | 19 | We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources" |
20 | in the AddEntropy function are fixed to 0. Second since no reliable timer is provided | |
20 | in the AddEntropy function are fixed to 0. Second since no reliable timer is provided | |
21 | 21 | we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */ |
22 | 22 | |
23 | #ifdef LTC_FORTUNA | |
23 | #ifdef LTC_FORTUNA | |
24 | 24 | |
25 | 25 | /* requries LTC_SHA256 and AES */ |
26 | 26 | #if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256)) |
78 | 78 | } |
79 | 79 | |
80 | 80 | for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
81 | if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { | |
81 | if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { | |
82 | 82 | /* terminate this hash */ |
83 | 83 | if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { |
84 | 84 | sha256_done(&md, tmp); |
85 | return err; | |
85 | return err; | |
86 | 86 | } |
87 | 87 | /* add it to the string */ |
88 | 88 | if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) { |
101 | 101 | |
102 | 102 | /* finish key */ |
103 | 103 | if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { |
104 | return err; | |
104 | return err; | |
105 | 105 | } |
106 | 106 | if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { |
107 | 107 | return err; |
125 | 125 | Start the PRNG |
126 | 126 | @param prng [out] The PRNG state to initialize |
127 | 127 | @return CRYPT_OK if successful |
128 | */ | |
128 | */ | |
129 | 129 | int fortuna_start(prng_state *prng) |
130 | 130 | { |
131 | 131 | int err, x, y; |
132 | 132 | unsigned char tmp[MAXBLOCKSIZE]; |
133 | 133 | |
134 | 134 | LTC_ARGCHK(prng != NULL); |
135 | ||
135 | ||
136 | 136 | /* initialize the pools */ |
137 | 137 | for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
138 | 138 | if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { |
154 | 154 | return err; |
155 | 155 | } |
156 | 156 | zeromem(prng->fortuna.IV, 16); |
157 | ||
157 | ||
158 | 158 | LTC_MUTEX_INIT(&prng->fortuna.prng_lock) |
159 | ||
159 | ||
160 | 160 | return CRYPT_OK; |
161 | 161 | } |
162 | 162 | |
166 | 166 | @param inlen Length of the data to add |
167 | 167 | @param prng PRNG state to update |
168 | 168 | @return CRYPT_OK if successful |
169 | */ | |
169 | */ | |
170 | 170 | int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) |
171 | 171 | { |
172 | 172 | unsigned char tmp[2]; |
209 | 209 | Make the PRNG ready to read from |
210 | 210 | @param prng The PRNG to make active |
211 | 211 | @return CRYPT_OK if successful |
212 | */ | |
212 | */ | |
213 | 213 | int fortuna_ready(prng_state *prng) |
214 | 214 | { |
215 | 215 | return fortuna_reseed(prng); |
221 | 221 | @param outlen Length of output |
222 | 222 | @param prng The active PRNG to read from |
223 | 223 | @return Number of octets read |
224 | */ | |
224 | */ | |
225 | 225 | unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng) |
226 | 226 | { |
227 | 227 | unsigned char tmp[16]; |
258 | 258 | XMEMCPY(out, tmp, outlen); |
259 | 259 | fortuna_update_iv(prng); |
260 | 260 | } |
261 | ||
261 | ||
262 | 262 | /* generate new key */ |
263 | rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey); | |
263 | rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey); | |
264 | 264 | fortuna_update_iv(prng); |
265 | ||
266 | rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey); | |
265 | ||
266 | rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey); | |
267 | 267 | fortuna_update_iv(prng); |
268 | ||
268 | ||
269 | 269 | if (rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey) != CRYPT_OK) { |
270 | 270 | LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
271 | 271 | return 0; |
276 | 276 | #endif |
277 | 277 | LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
278 | 278 | return tlen; |
279 | } | |
279 | } | |
280 | 280 | |
281 | 281 | /** |
282 | 282 | Terminate the PRNG |
283 | 283 | @param prng The PRNG to terminate |
284 | 284 | @return CRYPT_OK if successful |
285 | */ | |
285 | */ | |
286 | 286 | int fortuna_done(prng_state *prng) |
287 | 287 | { |
288 | 288 | int err, x; |
295 | 295 | for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
296 | 296 | if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { |
297 | 297 | LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
298 | return err; | |
298 | return err; | |
299 | 299 | } |
300 | 300 | } |
301 | 301 | /* call cipher done when we invent one ;-) */ |
314 | 314 | @param outlen [in/out] Max size and resulting size of the state |
315 | 315 | @param prng The PRNG to export |
316 | 316 | @return CRYPT_OK if successful |
317 | */ | |
317 | */ | |
318 | 318 | int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) |
319 | 319 | { |
320 | 320 | int x, err; |
339 | 339 | return CRYPT_MEM; |
340 | 340 | } |
341 | 341 | |
342 | /* to emit the state we copy each pool, terminate it then hash it again so | |
343 | * an attacker who sees the state can't determine the current state of the PRNG | |
344 | */ | |
342 | /* to emit the state we copy each pool, terminate it then hash it again so | |
343 | * an attacker who sees the state can't determine the current state of the PRNG | |
344 | */ | |
345 | 345 | for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
346 | 346 | /* copy the PRNG */ |
347 | 347 | XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); |
373 | 373 | LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); |
374 | 374 | return err; |
375 | 375 | } |
376 | ||
376 | ||
377 | 377 | /** |
378 | 378 | Import a PRNG state |
379 | 379 | @param in The PRNG state |
380 | 380 | @param inlen Size of the state |
381 | 381 | @param prng The PRNG to import |
382 | 382 | @return CRYPT_OK if successful |
383 | */ | |
383 | */ | |
384 | 384 | int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) |
385 | 385 | { |
386 | 386 | int err, x; |
406 | 406 | /** |
407 | 407 | PRNG self-test |
408 | 408 | @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled |
409 | */ | |
409 | */ | |
410 | 410 | int fortuna_test(void) |
411 | 411 | { |
412 | 412 | #ifndef LTC_TEST |
12 | 12 | /** |
13 | 13 | @file rc4.c |
14 | 14 | LTC_RC4 PRNG, Tom St Denis |
15 | */ | |
15 | */ | |
16 | 16 | |
17 | 17 | #ifdef LTC_RC4 |
18 | 18 | |
19 | const struct ltc_prng_descriptor rc4_desc = | |
19 | const struct ltc_prng_descriptor rc4_desc = | |
20 | 20 | { |
21 | 21 | "rc4", 32, |
22 | 22 | &rc4_start, |
33 | 33 | Start the PRNG |
34 | 34 | @param prng [out] The PRNG state to initialize |
35 | 35 | @return CRYPT_OK if successful |
36 | */ | |
36 | */ | |
37 | 37 | int rc4_start(prng_state *prng) |
38 | 38 | { |
39 | 39 | LTC_ARGCHK(prng != NULL); |
40 | 40 | |
41 | 41 | /* set keysize to zero */ |
42 | 42 | prng->rc4.x = 0; |
43 | ||
43 | ||
44 | 44 | return CRYPT_OK; |
45 | 45 | } |
46 | 46 | |
50 | 50 | @param inlen Length of the data to add |
51 | 51 | @param prng PRNG state to update |
52 | 52 | @return CRYPT_OK if successful |
53 | */ | |
53 | */ | |
54 | 54 | int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) |
55 | 55 | { |
56 | 56 | LTC_ARGCHK(in != NULL); |
57 | 57 | LTC_ARGCHK(prng != NULL); |
58 | ||
58 | ||
59 | 59 | /* trim as required */ |
60 | 60 | if (prng->rc4.x + inlen > 256) { |
61 | 61 | if (prng->rc4.x == 256) { |
64 | 64 | } else { |
65 | 65 | /* only accept part of it */ |
66 | 66 | inlen = 256 - prng->rc4.x; |
67 | } | |
67 | } | |
68 | 68 | } |
69 | 69 | |
70 | 70 | while (inlen--) { |
72 | 72 | } |
73 | 73 | |
74 | 74 | return CRYPT_OK; |
75 | ||
75 | ||
76 | 76 | } |
77 | 77 | |
78 | 78 | /** |
79 | 79 | Make the PRNG ready to read from |
80 | 80 | @param prng The PRNG to make active |
81 | 81 | @return CRYPT_OK if successful |
82 | */ | |
82 | */ | |
83 | 83 | int rc4_ready(prng_state *prng) |
84 | 84 | { |
85 | 85 | unsigned char key[256], tmp, *s; |
100 | 100 | for (j = x = y = 0; x < 256; x++) { |
101 | 101 | y = (y + prng->rc4.buf[x] + key[j++]) & 255; |
102 | 102 | if (j == keylen) { |
103 | j = 0; | |
103 | j = 0; | |
104 | 104 | } |
105 | 105 | tmp = s[x]; s[x] = s[y]; s[y] = tmp; |
106 | 106 | } |
120 | 120 | @param outlen Length of output |
121 | 121 | @param prng The active PRNG to read from |
122 | 122 | @return Number of octets read |
123 | */ | |
123 | */ | |
124 | 124 | unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng) |
125 | 125 | { |
126 | 126 | unsigned char x, y, *s, tmp; |
153 | 153 | Terminate the PRNG |
154 | 154 | @param prng The PRNG to terminate |
155 | 155 | @return CRYPT_OK if successful |
156 | */ | |
156 | */ | |
157 | 157 | int rc4_done(prng_state *prng) |
158 | 158 | { |
159 | 159 | LTC_ARGCHK(prng != NULL); |
166 | 166 | @param outlen [in/out] Max size and resulting size of the state |
167 | 167 | @param prng The PRNG to export |
168 | 168 | @return CRYPT_OK if successful |
169 | */ | |
169 | */ | |
170 | 170 | int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng) |
171 | 171 | { |
172 | 172 | LTC_ARGCHK(outlen != NULL); |
185 | 185 | |
186 | 186 | return CRYPT_OK; |
187 | 187 | } |
188 | ||
188 | ||
189 | 189 | /** |
190 | 190 | Import a PRNG state |
191 | 191 | @param in The PRNG state |
192 | 192 | @param inlen Size of the state |
193 | 193 | @param prng The PRNG to import |
194 | 194 | @return CRYPT_OK if successful |
195 | */ | |
195 | */ | |
196 | 196 | int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng) |
197 | 197 | { |
198 | 198 | int err; |
202 | 202 | if (inlen != 32) { |
203 | 203 | return CRYPT_INVALID_ARG; |
204 | 204 | } |
205 | ||
205 | ||
206 | 206 | if ((err = rc4_start(prng)) != CRYPT_OK) { |
207 | 207 | return err; |
208 | 208 | } |
212 | 212 | /** |
213 | 213 | PRNG self-test |
214 | 214 | @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled |
215 | */ | |
215 | */ | |
216 | 216 | int rc4_test(void) |
217 | 217 | { |
218 | 218 | #if !defined(LTC_TEST) || defined(LTC_VALGRIND) |
249 | 249 | if (XMEMCMP(dst, tests[x].ct, 8)) { |
250 | 250 | #if 0 |
251 | 251 | int y; |
252 | printf("\n\nLTC_RC4 failed, I got:\n"); | |
252 | printf("\n\nLTC_RC4 failed, I got:\n"); | |
253 | 253 | for (y = 0; y < 8; y++) printf("%02x ", dst[y]); |
254 | 254 | printf("\n"); |
255 | 255 | #endif |
310 | 310 | } |
311 | 311 | |
312 | 312 | #ifndef LTC_SMALL_CODE |
313 | /* do lots at a time, if there's enough to do */ | |
314 | while (outlen >= N*4) { | |
313 | /* do lots at a time, if there's enough to do */ | |
314 | while (outlen >= N*4) { | |
315 | 315 | SROUND(0); |
316 | 316 | SROUND(1); |
317 | 317 | SROUND(2); |
331 | 331 | SROUND(16); |
332 | 332 | out += 4*N; |
333 | 333 | outlen -= 4*N; |
334 | } | |
334 | } | |
335 | 335 | #endif |
336 | 336 | |
337 | /* do small or odd size buffers the slow way */ | |
338 | while (4 <= outlen) { | |
337 | /* do small or odd size buffers the slow way */ | |
338 | while (4 <= outlen) { | |
339 | 339 | cycle(c->R); |
340 | 340 | t = nltap(c); |
341 | 341 | XORWORD(t, out); |
342 | 342 | out += 4; |
343 | 343 | outlen -= 4; |
344 | } | |
345 | ||
346 | /* handle any trailing bytes */ | |
347 | if (outlen != 0) { | |
344 | } | |
345 | ||
346 | /* handle any trailing bytes */ | |
347 | if (outlen != 0) { | |
348 | 348 | cycle(c->R); |
349 | 349 | c->sbuf = nltap(c); |
350 | 350 | c->nbuf = 32; |
354 | 354 | c->nbuf -= 8; |
355 | 355 | --outlen; |
356 | 356 | } |
357 | } | |
358 | ||
359 | return tlen; | |
357 | } | |
358 | ||
359 | return tlen; | |
360 | 360 | } |
361 | 361 | |
362 | 362 | /** |