• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ====================================================================
2  * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the OpenSSL Project
19  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    licensing@OpenSSL.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  *    nor may "OpenSSL" appear in their names without prior written
28  *    permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the OpenSSL Project
33  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  */
49 
50 #include <openssl/opensslconf.h>
51 
52 #include <stdio.h>
53 #include <string.h>
54 
55 #if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
56 
57 #include <openssl/evp.h>
58 #include <openssl/objects.h>
59 #include <openssl/aes.h>
60 #include <openssl/sha.h>
61 #include "evp_locl.h"
62 
63 #ifndef EVP_CIPH_FLAG_AEAD_CIPHER
64 #define EVP_CIPH_FLAG_AEAD_CIPHER	0x200000
65 #define EVP_CTRL_AEAD_TLS1_AAD		0x16
66 #define EVP_CTRL_AEAD_SET_MAC_KEY	0x17
67 #endif
68 
69 #if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
70 #define EVP_CIPH_FLAG_DEFAULT_ASN1 0
71 #endif
72 
73 #define TLS1_1_VERSION 0x0302
74 
75 typedef struct
76     {
77     AES_KEY		ks;
78     SHA_CTX		head,tail,md;
79     size_t		payload_length;	/* AAD length in decrypt case */
80     union {
81 	unsigned int	tls_ver;
82     	unsigned char	tls_aad[16];	/* 13 used */
83     } aux;
84     } EVP_AES_HMAC_SHA1;
85 
86 #define NO_PAYLOAD_LENGTH	((size_t)-1)
87 
88 #if	defined(AES_ASM) &&	( \
89 	defined(__x86_64)	|| defined(__x86_64__)	|| \
90 	defined(_M_AMD64)	|| defined(_M_X64)	|| \
91 	defined(__INTEL__)	)
92 
93 extern unsigned int OPENSSL_ia32cap_P[2];
94 #define AESNI_CAPABLE   (1<<(57-32))
95 
96 int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
97 			      AES_KEY *key);
98 int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
99 			      AES_KEY *key);
100 
101 void aesni_cbc_encrypt(const unsigned char *in,
102 			   unsigned char *out,
103 			   size_t length,
104 			   const AES_KEY *key,
105 			   unsigned char *ivec, int enc);
106 
107 void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
108 		const AES_KEY *key, unsigned char iv[16],
109 		SHA_CTX *ctx,const void *in0);
110 
111 #define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
112 
aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * inkey,const unsigned char * iv,int enc)113 static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
114 			const unsigned char *inkey,
115 			const unsigned char *iv, int enc)
116 	{
117 	EVP_AES_HMAC_SHA1 *key = data(ctx);
118 	int ret;
119 
120 	if (enc)
121 		ret=aesni_set_encrypt_key(inkey,ctx->key_len*8,&key->ks);
122 	else
123 		ret=aesni_set_decrypt_key(inkey,ctx->key_len*8,&key->ks);
124 
125 	SHA1_Init(&key->head);	/* handy when benchmarking */
126 	key->tail = key->head;
127 	key->md   = key->head;
128 
129 	key->payload_length = NO_PAYLOAD_LENGTH;
130 
131 	return ret<0?0:1;
132 	}
133 
134 #define	STITCHED_CALL
135 
136 #if !defined(STITCHED_CALL)
137 #define	aes_off 0
138 #endif
139 
140 void sha1_block_data_order (void *c,const void *p,size_t len);
141 
sha1_update(SHA_CTX * c,const void * data,size_t len)142 static void sha1_update(SHA_CTX *c,const void *data,size_t len)
143 {	const unsigned char *ptr = data;
144 	size_t res;
145 
146 	if ((res = c->num)) {
147 		res = SHA_CBLOCK-res;
148 		if (len<res) res=len;
149 		SHA1_Update (c,ptr,res);
150 		ptr += res;
151 		len -= res;
152 	}
153 
154 	res = len % SHA_CBLOCK;
155 	len -= res;
156 
157 	if (len) {
158 		sha1_block_data_order(c,ptr,len/SHA_CBLOCK);
159 
160 		ptr += len;
161 		c->Nh += len>>29;
162 		c->Nl += len<<=3;
163 		if (c->Nl<(unsigned int)len) c->Nh++;
164 	}
165 
166 	if (res)
167 		SHA1_Update(c,ptr,res);
168 }
169 
170 #define SHA1_Update sha1_update
171 
aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)172 static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
173 		      const unsigned char *in, size_t len)
174 	{
175 	EVP_AES_HMAC_SHA1 *key = data(ctx);
176 	unsigned int l;
177 	size_t	plen = key->payload_length,
178 		iv = 0,		/* explicit IV in TLS 1.1 and later */
179 		sha_off = 0;
180 #if defined(STITCHED_CALL)
181 	size_t	aes_off = 0,
182 		blocks;
183 
184 	sha_off = SHA_CBLOCK-key->md.num;
185 #endif
186 
187 	if (len%AES_BLOCK_SIZE) return 0;
188 
189 	if (ctx->encrypt) {
190 		if (plen==NO_PAYLOAD_LENGTH)
191 			plen = len;
192 		else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
193 			return 0;
194 		else if (key->aux.tls_ver >= TLS1_1_VERSION)
195 			iv = AES_BLOCK_SIZE;
196 
197 #if defined(STITCHED_CALL)
198 		if (plen>(sha_off+iv) && (blocks=(plen-(sha_off+iv))/SHA_CBLOCK)) {
199 			SHA1_Update(&key->md,in+iv,sha_off);
200 
201 			aesni_cbc_sha1_enc(in,out,blocks,&key->ks,
202 				ctx->iv,&key->md,in+iv+sha_off);
203 			blocks *= SHA_CBLOCK;
204 			aes_off += blocks;
205 			sha_off += blocks;
206 			key->md.Nh += blocks>>29;
207 			key->md.Nl += blocks<<=3;
208 			if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
209 		} else {
210 			sha_off = 0;
211 		}
212 #endif
213 		sha_off += iv;
214 		SHA1_Update(&key->md,in+sha_off,plen-sha_off);
215 
216 		if (plen!=len)	{	/* "TLS" mode of operation */
217 			if (in!=out)
218 				memcpy(out+aes_off,in+aes_off,plen-aes_off);
219 
220 			/* calculate HMAC and append it to payload */
221 			SHA1_Final(out+plen,&key->md);
222 			key->md = key->tail;
223 			SHA1_Update(&key->md,out+plen,SHA_DIGEST_LENGTH);
224 			SHA1_Final(out+plen,&key->md);
225 
226 			/* pad the payload|hmac */
227 			plen += SHA_DIGEST_LENGTH;
228 			for (l=len-plen-1;plen<len;plen++) out[plen]=l;
229 			/* encrypt HMAC|padding at once */
230 			aesni_cbc_encrypt(out+aes_off,out+aes_off,len-aes_off,
231 					&key->ks,ctx->iv,1);
232 		} else {
233 			aesni_cbc_encrypt(in+aes_off,out+aes_off,len-aes_off,
234 					&key->ks,ctx->iv,1);
235 		}
236 	} else {
237 		unsigned char mac[SHA_DIGEST_LENGTH];
238 
239 		/* decrypt HMAC|padding at once */
240 		aesni_cbc_encrypt(in,out,len,
241 				&key->ks,ctx->iv,0);
242 
243 		if (plen) {	/* "TLS" mode of operation */
244 			/* figure out payload length */
245 			if (len<(size_t)(out[len-1]+1+SHA_DIGEST_LENGTH))
246 				return 0;
247 
248 			len -= (out[len-1]+1+SHA_DIGEST_LENGTH);
249 
250 			if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
251 			    >= TLS1_1_VERSION) {
252 				len -= AES_BLOCK_SIZE;
253 				iv = AES_BLOCK_SIZE;
254 			}
255 
256 			key->aux.tls_aad[plen-2] = len>>8;
257 			key->aux.tls_aad[plen-1] = len;
258 
259 			/* calculate HMAC and verify it */
260 			key->md = key->head;
261 			SHA1_Update(&key->md,key->aux.tls_aad,plen);
262 			SHA1_Update(&key->md,out+iv,len);
263 			SHA1_Final(mac,&key->md);
264 
265 			key->md = key->tail;
266 			SHA1_Update(&key->md,mac,SHA_DIGEST_LENGTH);
267 			SHA1_Final(mac,&key->md);
268 
269 			if (memcmp(out+iv+len,mac,SHA_DIGEST_LENGTH))
270 				return 0;
271 		} else {
272 			SHA1_Update(&key->md,out,len);
273 		}
274 	}
275 
276 	key->payload_length = NO_PAYLOAD_LENGTH;
277 
278 	return 1;
279 	}
280 
aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX * ctx,int type,int arg,void * ptr)281 static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
282 	{
283 	EVP_AES_HMAC_SHA1 *key = data(ctx);
284 
285 	switch (type)
286 		{
287 	case EVP_CTRL_AEAD_SET_MAC_KEY:
288 		{
289 		unsigned int  i;
290 		unsigned char hmac_key[64];
291 
292 		memset (hmac_key,0,sizeof(hmac_key));
293 
294 		if (arg > (int)sizeof(hmac_key)) {
295 			SHA1_Init(&key->head);
296 			SHA1_Update(&key->head,ptr,arg);
297 			SHA1_Final(hmac_key,&key->head);
298 		} else {
299 			memcpy(hmac_key,ptr,arg);
300 		}
301 
302 		for (i=0;i<sizeof(hmac_key);i++)
303 			hmac_key[i] ^= 0x36;		/* ipad */
304 		SHA1_Init(&key->head);
305 		SHA1_Update(&key->head,hmac_key,sizeof(hmac_key));
306 
307 		for (i=0;i<sizeof(hmac_key);i++)
308 			hmac_key[i] ^= 0x36^0x5c;	/* opad */
309 		SHA1_Init(&key->tail);
310 		SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
311 
312 		return 1;
313 		}
314 	case EVP_CTRL_AEAD_TLS1_AAD:
315 		{
316 		unsigned char *p=ptr;
317 		unsigned int   len=p[arg-2]<<8|p[arg-1];
318 
319 		if (ctx->encrypt)
320 			{
321 			key->payload_length = len;
322 			if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
323 				len -= AES_BLOCK_SIZE;
324 				p[arg-2] = len>>8;
325 				p[arg-1] = len;
326 			}
327 			key->md = key->head;
328 			SHA1_Update(&key->md,p,arg);
329 
330 			return (int)(((len+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
331 				- len);
332 			}
333 		else
334 			{
335 			if (arg>13) arg = 13;
336 			memcpy(key->aux.tls_aad,ptr,arg);
337 			key->payload_length = arg;
338 
339 			return SHA_DIGEST_LENGTH;
340 			}
341 		}
342 	default:
343 		return -1;
344 		}
345 	}
346 
347 static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher =
348 	{
349 #ifdef NID_aes_128_cbc_hmac_sha1
350 	NID_aes_128_cbc_hmac_sha1,
351 #else
352 	NID_undef,
353 #endif
354 	16,16,16,
355 	EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
356 	aesni_cbc_hmac_sha1_init_key,
357 	aesni_cbc_hmac_sha1_cipher,
358 	NULL,
359 	sizeof(EVP_AES_HMAC_SHA1),
360 	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
361 	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
362 	aesni_cbc_hmac_sha1_ctrl,
363 	NULL
364 	};
365 
366 static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher =
367 	{
368 #ifdef NID_aes_256_cbc_hmac_sha1
369 	NID_aes_256_cbc_hmac_sha1,
370 #else
371 	NID_undef,
372 #endif
373 	16,32,16,
374 	EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
375 	aesni_cbc_hmac_sha1_init_key,
376 	aesni_cbc_hmac_sha1_cipher,
377 	NULL,
378 	sizeof(EVP_AES_HMAC_SHA1),
379 	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
380 	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
381 	aesni_cbc_hmac_sha1_ctrl,
382 	NULL
383 	};
384 
EVP_aes_128_cbc_hmac_sha1(void)385 const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
386 	{
387 	return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
388 		&aesni_128_cbc_hmac_sha1_cipher:NULL);
389 	}
390 
EVP_aes_256_cbc_hmac_sha1(void)391 const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
392 	{
393 	return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
394 		&aesni_256_cbc_hmac_sha1_cipher:NULL);
395 	}
396 #else
EVP_aes_128_cbc_hmac_sha1(void)397 const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
398 	{
399 	return NULL;
400 	}
EVP_aes_256_cbc_hmac_sha1(void)401 const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
402 	{
403 	return NULL;
404 	}
405 #endif
406 #endif
407