Mercurial > dropbear
comparison libtomcrypt/src/encauth/ocb3/ocb3_init.c @ 1471:6dba84798cd5
Update to libtomcrypt 1.18.1, merged with Dropbear changes
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 09 Feb 2018 21:44:05 +0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1470:8bba51a55704 | 1471:6dba84798cd5 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 */ | |
9 | |
10 /** | |
11 @file ocb3_init.c | |
12 OCB implementation, initialize state, by Tom St Denis | |
13 */ | |
14 #include "tomcrypt.h" | |
15 | |
16 #ifdef LTC_OCB3_MODE | |
17 | |
18 static void _ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen) | |
19 { | |
20 int x, y, bottom; | |
21 int idx, shift; | |
22 unsigned char iNonce[MAXBLOCKSIZE]; | |
23 unsigned char iKtop[MAXBLOCKSIZE]; | |
24 unsigned char iStretch[MAXBLOCKSIZE+8]; | |
25 | |
26 /* Nonce = zeros(127-bitlen(N)) || 1 || N */ | |
27 zeromem(iNonce, sizeof(iNonce)); | |
28 for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) { | |
29 iNonce[x] = nonce[noncelen-y-1]; | |
30 } | |
31 iNonce[x] = 0x01; | |
32 iNonce[0] |= ((taglen*8) % 128) << 1; | |
33 | |
34 /* bottom = str2num(Nonce[123..128]) */ | |
35 bottom = iNonce[ocb->block_len-1] & 0x3F; | |
36 | |
37 /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */ | |
38 iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0; | |
39 if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) { | |
40 zeromem(ocb->Offset_current, ocb->block_len); | |
41 return; | |
42 } | |
43 | |
44 /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ | |
45 for (x = 0; x < ocb->block_len; x++) { | |
46 iStretch[x] = iKtop[x]; | |
47 } | |
48 for (y = 0; y < 8; y++) { | |
49 iStretch[x+y] = iKtop[y] ^ iKtop[y+1]; | |
50 } | |
51 | |
52 /* Offset_0 = Stretch[1+bottom..128+bottom] */ | |
53 idx = bottom / 8; | |
54 shift = (bottom % 8); | |
55 for (x = 0; x < ocb->block_len; x++) { | |
56 ocb->Offset_current[x] = iStretch[idx+x] << shift; | |
57 if (shift > 0) { | |
58 ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift); | |
59 } | |
60 } | |
61 } | |
62 | |
63 static const struct { | |
64 int len; | |
65 unsigned char poly_mul[MAXBLOCKSIZE]; | |
66 } polys[] = { | |
67 { | |
68 8, | |
69 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } | |
70 }, { | |
71 16, | |
72 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } | |
74 } | |
75 }; | |
76 | |
77 /** | |
78 Initialize an OCB context | |
79 @param ocb [out] The destination of the OCB state | |
80 @param cipher The index of the desired cipher | |
81 @param key The secret key | |
82 @param keylen The length of the secret key (octets) | |
83 @param nonce The session nonce | |
84 @param noncelen The length of the session nonce (octets, up to 15) | |
85 @param taglen The length of the tag (octets, up to 16) | |
86 @return CRYPT_OK if successful | |
87 */ | |
88 int ocb3_init(ocb3_state *ocb, int cipher, | |
89 const unsigned char *key, unsigned long keylen, | |
90 const unsigned char *nonce, unsigned long noncelen, | |
91 unsigned long taglen) | |
92 { | |
93 int poly, x, y, m, err; | |
94 unsigned char *previous, *current; | |
95 | |
96 LTC_ARGCHK(ocb != NULL); | |
97 LTC_ARGCHK(key != NULL); | |
98 LTC_ARGCHK(nonce != NULL); | |
99 | |
100 /* valid cipher? */ | |
101 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { | |
102 return err; | |
103 } | |
104 ocb->cipher = cipher; | |
105 | |
106 /* Valid Nonce? | |
107 * As of RFC7253: "string of no more than 120 bits" */ | |
108 if (noncelen > (120/8)) { | |
109 return CRYPT_INVALID_ARG; | |
110 } | |
111 | |
112 /* The blockcipher must have a 128-bit blocksize */ | |
113 if (cipher_descriptor[cipher].block_length != 16) { | |
114 return CRYPT_INVALID_ARG; | |
115 } | |
116 | |
117 /* The TAGLEN may be any value up to 128 (bits) */ | |
118 if (taglen > 16) { | |
119 return CRYPT_INVALID_ARG; | |
120 } | |
121 ocb->tag_len = taglen; | |
122 | |
123 /* determine which polys to use */ | |
124 ocb->block_len = cipher_descriptor[cipher].block_length; | |
125 x = (int)(sizeof(polys)/sizeof(polys[0])); | |
126 for (poly = 0; poly < x; poly++) { | |
127 if (polys[poly].len == ocb->block_len) { | |
128 break; | |
129 } | |
130 } | |
131 if (poly == x) { | |
132 return CRYPT_INVALID_ARG; /* block_len not found in polys */ | |
133 } | |
134 if (polys[poly].len != ocb->block_len) { | |
135 return CRYPT_INVALID_ARG; | |
136 } | |
137 | |
138 /* schedule the key */ | |
139 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { | |
140 return err; | |
141 } | |
142 | |
143 /* L_* = ENCIPHER(K, zeros(128)) */ | |
144 zeromem(ocb->L_star, ocb->block_len); | |
145 if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) { | |
146 return err; | |
147 } | |
148 | |
149 /* compute L_$, L_0, L_1, ... */ | |
150 for (x = -1; x < 32; x++) { | |
151 if (x == -1) { /* gonna compute: L_$ = double(L_*) */ | |
152 current = ocb->L_dollar; | |
153 previous = ocb->L_star; | |
154 } | |
155 else if (x == 0) { /* gonna compute: L_0 = double(L_$) */ | |
156 current = ocb->L_[0]; | |
157 previous = ocb->L_dollar; | |
158 } | |
159 else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */ | |
160 current = ocb->L_[x]; | |
161 previous = ocb->L_[x-1]; | |
162 } | |
163 m = previous[0] >> 7; | |
164 for (y = 0; y < ocb->block_len-1; y++) { | |
165 current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255; | |
166 } | |
167 current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255; | |
168 if (m == 1) { | |
169 /* current[] = current[] XOR polys[poly].poly_mul[]*/ | |
170 ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len); | |
171 } | |
172 } | |
173 | |
174 /* initialize ocb->Offset_current = Offset_0 */ | |
175 _ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen); | |
176 | |
177 /* initialize checksum to all zeros */ | |
178 zeromem(ocb->checksum, ocb->block_len); | |
179 | |
180 /* set block index */ | |
181 ocb->block_index = 1; | |
182 | |
183 /* initialize AAD related stuff */ | |
184 ocb->ablock_index = 1; | |
185 ocb->adata_buffer_bytes = 0; | |
186 zeromem(ocb->aOffset_current, ocb->block_len); | |
187 zeromem(ocb->aSum_current, ocb->block_len); | |
188 | |
189 return CRYPT_OK; | |
190 } | |
191 | |
192 #endif | |
193 | |
194 /* ref: $Format:%D$ */ | |
195 /* git commit: $Format:%H$ */ | |
196 /* commit time: $Format:%ai$ */ |