e_aes_cbc_hmac_sha1.c revision 246772
1238384Sjkim/* ====================================================================
2246772Sjkim * Copyright (c) 2011-2013 The OpenSSL Project.  All rights reserved.
3238384Sjkim *
4238384Sjkim * Redistribution and use in source and binary forms, with or without
5238384Sjkim * modification, are permitted provided that the following conditions
6238384Sjkim * are met:
7238384Sjkim *
8238384Sjkim * 1. Redistributions of source code must retain the above copyright
9238384Sjkim *    notice, this list of conditions and the following disclaimer.
10238384Sjkim *
11238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright
12238384Sjkim *    notice, this list of conditions and the following disclaimer in
13238384Sjkim *    the documentation and/or other materials provided with the
14238384Sjkim *    distribution.
15238384Sjkim *
16238384Sjkim * 3. All advertising materials mentioning features or use of this
17238384Sjkim *    software must display the following acknowledgment:
18238384Sjkim *    "This product includes software developed by the OpenSSL Project
19238384Sjkim *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20238384Sjkim *
21238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22238384Sjkim *    endorse or promote products derived from this software without
23238384Sjkim *    prior written permission. For written permission, please contact
24238384Sjkim *    licensing@OpenSSL.org.
25238384Sjkim *
26238384Sjkim * 5. Products derived from this software may not be called "OpenSSL"
27238384Sjkim *    nor may "OpenSSL" appear in their names without prior written
28238384Sjkim *    permission of the OpenSSL Project.
29238384Sjkim *
30238384Sjkim * 6. Redistributions of any form whatsoever must retain the following
31238384Sjkim *    acknowledgment:
32238384Sjkim *    "This product includes software developed by the OpenSSL Project
33238384Sjkim *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34238384Sjkim *
35238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38238384Sjkim * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE.
47238384Sjkim * ====================================================================
48238384Sjkim */
49238384Sjkim
50238384Sjkim#include <openssl/opensslconf.h>
51238384Sjkim
52238384Sjkim#include <stdio.h>
53238384Sjkim#include <string.h>
54238384Sjkim
55238384Sjkim#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
56238384Sjkim
57238384Sjkim#include <openssl/evp.h>
58238384Sjkim#include <openssl/objects.h>
59238384Sjkim#include <openssl/aes.h>
60238384Sjkim#include <openssl/sha.h>
61238384Sjkim#include "evp_locl.h"
62238384Sjkim
63238384Sjkim#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
64238384Sjkim#define EVP_CIPH_FLAG_AEAD_CIPHER	0x200000
65238384Sjkim#define EVP_CTRL_AEAD_TLS1_AAD		0x16
66238384Sjkim#define EVP_CTRL_AEAD_SET_MAC_KEY	0x17
67238384Sjkim#endif
68238384Sjkim
69238384Sjkim#if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
70238384Sjkim#define EVP_CIPH_FLAG_DEFAULT_ASN1 0
71238384Sjkim#endif
72238384Sjkim
73238384Sjkim#define TLS1_1_VERSION 0x0302
74238384Sjkim
75238384Sjkimtypedef struct
76238384Sjkim    {
77238384Sjkim    AES_KEY		ks;
78238384Sjkim    SHA_CTX		head,tail,md;
79238384Sjkim    size_t		payload_length;	/* AAD length in decrypt case */
80238384Sjkim    union {
81238384Sjkim	unsigned int	tls_ver;
82238384Sjkim    	unsigned char	tls_aad[16];	/* 13 used */
83238384Sjkim    } aux;
84238384Sjkim    } EVP_AES_HMAC_SHA1;
85238384Sjkim
86238384Sjkim#define NO_PAYLOAD_LENGTH	((size_t)-1)
87238384Sjkim
88238384Sjkim#if	defined(AES_ASM) &&	( \
89238384Sjkim	defined(__x86_64)	|| defined(__x86_64__)	|| \
90238384Sjkim	defined(_M_AMD64)	|| defined(_M_X64)	|| \
91238384Sjkim	defined(__INTEL__)	)
92238384Sjkim
93246772Sjkim#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
94246772Sjkim# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
95246772Sjkim#endif
96246772Sjkim
97238384Sjkimextern unsigned int OPENSSL_ia32cap_P[2];
98238384Sjkim#define AESNI_CAPABLE   (1<<(57-32))
99238384Sjkim
100238384Sjkimint aesni_set_encrypt_key(const unsigned char *userKey, int bits,
101238384Sjkim			      AES_KEY *key);
102238384Sjkimint aesni_set_decrypt_key(const unsigned char *userKey, int bits,
103238384Sjkim			      AES_KEY *key);
104238384Sjkim
105238384Sjkimvoid aesni_cbc_encrypt(const unsigned char *in,
106238384Sjkim			   unsigned char *out,
107238384Sjkim			   size_t length,
108238384Sjkim			   const AES_KEY *key,
109238384Sjkim			   unsigned char *ivec, int enc);
110238384Sjkim
111238384Sjkimvoid aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
112238384Sjkim		const AES_KEY *key, unsigned char iv[16],
113238384Sjkim		SHA_CTX *ctx,const void *in0);
114238384Sjkim
115238384Sjkim#define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
116238384Sjkim
117238384Sjkimstatic int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
118238384Sjkim			const unsigned char *inkey,
119238384Sjkim			const unsigned char *iv, int enc)
120238384Sjkim	{
121238384Sjkim	EVP_AES_HMAC_SHA1 *key = data(ctx);
122238384Sjkim	int ret;
123238384Sjkim
124238384Sjkim	if (enc)
125238384Sjkim		ret=aesni_set_encrypt_key(inkey,ctx->key_len*8,&key->ks);
126238384Sjkim	else
127238384Sjkim		ret=aesni_set_decrypt_key(inkey,ctx->key_len*8,&key->ks);
128238384Sjkim
129238384Sjkim	SHA1_Init(&key->head);	/* handy when benchmarking */
130238384Sjkim	key->tail = key->head;
131238384Sjkim	key->md   = key->head;
132238384Sjkim
133238384Sjkim	key->payload_length = NO_PAYLOAD_LENGTH;
134238384Sjkim
135238384Sjkim	return ret<0?0:1;
136238384Sjkim	}
137238384Sjkim
138238384Sjkim#define	STITCHED_CALL
139238384Sjkim
140238384Sjkim#if !defined(STITCHED_CALL)
141238384Sjkim#define	aes_off 0
142238384Sjkim#endif
143238384Sjkim
144238384Sjkimvoid sha1_block_data_order (void *c,const void *p,size_t len);
145238384Sjkim
146238384Sjkimstatic void sha1_update(SHA_CTX *c,const void *data,size_t len)
147238384Sjkim{	const unsigned char *ptr = data;
148238384Sjkim	size_t res;
149238384Sjkim
150238384Sjkim	if ((res = c->num)) {
151238384Sjkim		res = SHA_CBLOCK-res;
152238384Sjkim		if (len<res) res=len;
153238384Sjkim		SHA1_Update (c,ptr,res);
154238384Sjkim		ptr += res;
155238384Sjkim		len -= res;
156238384Sjkim	}
157238384Sjkim
158238384Sjkim	res = len % SHA_CBLOCK;
159238384Sjkim	len -= res;
160238384Sjkim
161238384Sjkim	if (len) {
162238384Sjkim		sha1_block_data_order(c,ptr,len/SHA_CBLOCK);
163238384Sjkim
164238384Sjkim		ptr += len;
165238384Sjkim		c->Nh += len>>29;
166238384Sjkim		c->Nl += len<<=3;
167238384Sjkim		if (c->Nl<(unsigned int)len) c->Nh++;
168238384Sjkim	}
169238384Sjkim
170238384Sjkim	if (res)
171238384Sjkim		SHA1_Update(c,ptr,res);
172238384Sjkim}
173238384Sjkim
174246772Sjkim#ifdef SHA1_Update
175246772Sjkim#undef SHA1_Update
176246772Sjkim#endif
177238384Sjkim#define SHA1_Update sha1_update
178238384Sjkim
179238384Sjkimstatic int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
180238384Sjkim		      const unsigned char *in, size_t len)
181238384Sjkim	{
182238384Sjkim	EVP_AES_HMAC_SHA1 *key = data(ctx);
183238384Sjkim	unsigned int l;
184238384Sjkim	size_t	plen = key->payload_length,
185238384Sjkim		iv = 0,		/* explicit IV in TLS 1.1 and later */
186238384Sjkim		sha_off = 0;
187238384Sjkim#if defined(STITCHED_CALL)
188238384Sjkim	size_t	aes_off = 0,
189238384Sjkim		blocks;
190238384Sjkim
191238384Sjkim	sha_off = SHA_CBLOCK-key->md.num;
192238384Sjkim#endif
193238384Sjkim
194246772Sjkim	key->payload_length = NO_PAYLOAD_LENGTH;
195246772Sjkim
196238384Sjkim	if (len%AES_BLOCK_SIZE) return 0;
197238384Sjkim
198238384Sjkim	if (ctx->encrypt) {
199238384Sjkim		if (plen==NO_PAYLOAD_LENGTH)
200238384Sjkim			plen = len;
201238384Sjkim		else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
202238384Sjkim			return 0;
203238384Sjkim		else if (key->aux.tls_ver >= TLS1_1_VERSION)
204238384Sjkim			iv = AES_BLOCK_SIZE;
205238384Sjkim
206238384Sjkim#if defined(STITCHED_CALL)
207238384Sjkim		if (plen>(sha_off+iv) && (blocks=(plen-(sha_off+iv))/SHA_CBLOCK)) {
208238384Sjkim			SHA1_Update(&key->md,in+iv,sha_off);
209238384Sjkim
210238384Sjkim			aesni_cbc_sha1_enc(in,out,blocks,&key->ks,
211238384Sjkim				ctx->iv,&key->md,in+iv+sha_off);
212238384Sjkim			blocks *= SHA_CBLOCK;
213238384Sjkim			aes_off += blocks;
214238384Sjkim			sha_off += blocks;
215238384Sjkim			key->md.Nh += blocks>>29;
216238384Sjkim			key->md.Nl += blocks<<=3;
217238384Sjkim			if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
218238384Sjkim		} else {
219238384Sjkim			sha_off = 0;
220238384Sjkim		}
221238384Sjkim#endif
222238384Sjkim		sha_off += iv;
223238384Sjkim		SHA1_Update(&key->md,in+sha_off,plen-sha_off);
224238384Sjkim
225238384Sjkim		if (plen!=len)	{	/* "TLS" mode of operation */
226238384Sjkim			if (in!=out)
227238384Sjkim				memcpy(out+aes_off,in+aes_off,plen-aes_off);
228238384Sjkim
229238384Sjkim			/* calculate HMAC and append it to payload */
230238384Sjkim			SHA1_Final(out+plen,&key->md);
231238384Sjkim			key->md = key->tail;
232238384Sjkim			SHA1_Update(&key->md,out+plen,SHA_DIGEST_LENGTH);
233238384Sjkim			SHA1_Final(out+plen,&key->md);
234238384Sjkim
235238384Sjkim			/* pad the payload|hmac */
236238384Sjkim			plen += SHA_DIGEST_LENGTH;
237238384Sjkim			for (l=len-plen-1;plen<len;plen++) out[plen]=l;
238238384Sjkim			/* encrypt HMAC|padding at once */
239238384Sjkim			aesni_cbc_encrypt(out+aes_off,out+aes_off,len-aes_off,
240238384Sjkim					&key->ks,ctx->iv,1);
241238384Sjkim		} else {
242238384Sjkim			aesni_cbc_encrypt(in+aes_off,out+aes_off,len-aes_off,
243238384Sjkim					&key->ks,ctx->iv,1);
244238384Sjkim		}
245238384Sjkim	} else {
246246772Sjkim		union { unsigned int  u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
247246772Sjkim			unsigned char c[32+SHA_DIGEST_LENGTH]; } mac, *pmac;
248238384Sjkim
249246772Sjkim		/* arrange cache line alignment */
250246772Sjkim		pmac = (void *)(((size_t)mac.c+31)&((size_t)0-32));
251246772Sjkim
252238384Sjkim		/* decrypt HMAC|padding at once */
253238384Sjkim		aesni_cbc_encrypt(in,out,len,
254238384Sjkim				&key->ks,ctx->iv,0);
255238384Sjkim
256238384Sjkim		if (plen) {	/* "TLS" mode of operation */
257246772Sjkim			size_t inp_len, mask, j, i;
258246772Sjkim			unsigned int res, maxpad, pad, bitlen;
259246772Sjkim			int ret = 1;
260246772Sjkim			union {	unsigned int  u[SHA_LBLOCK];
261246772Sjkim				unsigned char c[SHA_CBLOCK]; }
262246772Sjkim				*data = (void *)key->md.data;
263238384Sjkim
264238384Sjkim			if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
265246772Sjkim			    >= TLS1_1_VERSION)
266238384Sjkim				iv = AES_BLOCK_SIZE;
267238384Sjkim
268246772Sjkim			if (len<(iv+SHA_DIGEST_LENGTH+1))
269246772Sjkim				return 0;
270238384Sjkim
271246772Sjkim			/* omit explicit iv */
272246772Sjkim			out += iv;
273246772Sjkim			len -= iv;
274246772Sjkim
275246772Sjkim			/* figure out payload length */
276246772Sjkim			pad = out[len-1];
277246772Sjkim			maxpad = len-(SHA_DIGEST_LENGTH+1);
278246772Sjkim			maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
279246772Sjkim			maxpad &= 255;
280246772Sjkim
281246772Sjkim			inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
282246772Sjkim			mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
283246772Sjkim			inp_len &= mask;
284246772Sjkim			ret &= (int)mask;
285246772Sjkim
286246772Sjkim			key->aux.tls_aad[plen-2] = inp_len>>8;
287246772Sjkim			key->aux.tls_aad[plen-1] = inp_len;
288246772Sjkim
289246772Sjkim			/* calculate HMAC */
290238384Sjkim			key->md = key->head;
291238384Sjkim			SHA1_Update(&key->md,key->aux.tls_aad,plen);
292238384Sjkim
293246772Sjkim#if 1
294246772Sjkim			len -= SHA_DIGEST_LENGTH;		/* amend mac */
295246772Sjkim			if (len>=(256+SHA_CBLOCK)) {
296246772Sjkim				j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK);
297246772Sjkim				j += SHA_CBLOCK-key->md.num;
298246772Sjkim				SHA1_Update(&key->md,out,j);
299246772Sjkim				out += j;
300246772Sjkim				len -= j;
301246772Sjkim				inp_len -= j;
302246772Sjkim			}
303246772Sjkim
304246772Sjkim			/* but pretend as if we hashed padded payload */
305246772Sjkim			bitlen = key->md.Nl+(inp_len<<3);	/* at most 18 bits */
306246772Sjkim#ifdef BSWAP
307246772Sjkim			bitlen = BSWAP(bitlen);
308246772Sjkim#else
309246772Sjkim			mac.c[0] = 0;
310246772Sjkim			mac.c[1] = (unsigned char)(bitlen>>16);
311246772Sjkim			mac.c[2] = (unsigned char)(bitlen>>8);
312246772Sjkim			mac.c[3] = (unsigned char)bitlen;
313246772Sjkim			bitlen = mac.u[0];
314246772Sjkim#endif
315246772Sjkim
316246772Sjkim			pmac->u[0]=0;
317246772Sjkim			pmac->u[1]=0;
318246772Sjkim			pmac->u[2]=0;
319246772Sjkim			pmac->u[3]=0;
320246772Sjkim			pmac->u[4]=0;
321246772Sjkim
322246772Sjkim			for (res=key->md.num, j=0;j<len;j++) {
323246772Sjkim				size_t c = out[j];
324246772Sjkim				mask = (j-inp_len)>>(sizeof(j)*8-8);
325246772Sjkim				c &= mask;
326246772Sjkim				c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
327246772Sjkim				data->c[res++]=(unsigned char)c;
328246772Sjkim
329246772Sjkim				if (res!=SHA_CBLOCK) continue;
330246772Sjkim
331246772Sjkim				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
332246772Sjkim				data->u[SHA_LBLOCK-1] |= bitlen&mask;
333246772Sjkim				sha1_block_data_order(&key->md,data,1);
334246772Sjkim				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
335246772Sjkim				pmac->u[0] |= key->md.h0 & mask;
336246772Sjkim				pmac->u[1] |= key->md.h1 & mask;
337246772Sjkim				pmac->u[2] |= key->md.h2 & mask;
338246772Sjkim				pmac->u[3] |= key->md.h3 & mask;
339246772Sjkim				pmac->u[4] |= key->md.h4 & mask;
340246772Sjkim				res=0;
341246772Sjkim			}
342246772Sjkim
343246772Sjkim			for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0;
344246772Sjkim
345246772Sjkim			if (res>SHA_CBLOCK-8) {
346246772Sjkim				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
347246772Sjkim				data->u[SHA_LBLOCK-1] |= bitlen&mask;
348246772Sjkim				sha1_block_data_order(&key->md,data,1);
349246772Sjkim				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
350246772Sjkim				pmac->u[0] |= key->md.h0 & mask;
351246772Sjkim				pmac->u[1] |= key->md.h1 & mask;
352246772Sjkim				pmac->u[2] |= key->md.h2 & mask;
353246772Sjkim				pmac->u[3] |= key->md.h3 & mask;
354246772Sjkim				pmac->u[4] |= key->md.h4 & mask;
355246772Sjkim
356246772Sjkim				memset(data,0,SHA_CBLOCK);
357246772Sjkim				j+=64;
358246772Sjkim			}
359246772Sjkim			data->u[SHA_LBLOCK-1] = bitlen;
360246772Sjkim			sha1_block_data_order(&key->md,data,1);
361246772Sjkim			mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
362246772Sjkim			pmac->u[0] |= key->md.h0 & mask;
363246772Sjkim			pmac->u[1] |= key->md.h1 & mask;
364246772Sjkim			pmac->u[2] |= key->md.h2 & mask;
365246772Sjkim			pmac->u[3] |= key->md.h3 & mask;
366246772Sjkim			pmac->u[4] |= key->md.h4 & mask;
367246772Sjkim
368246772Sjkim#ifdef BSWAP
369246772Sjkim			pmac->u[0] = BSWAP(pmac->u[0]);
370246772Sjkim			pmac->u[1] = BSWAP(pmac->u[1]);
371246772Sjkim			pmac->u[2] = BSWAP(pmac->u[2]);
372246772Sjkim			pmac->u[3] = BSWAP(pmac->u[3]);
373246772Sjkim			pmac->u[4] = BSWAP(pmac->u[4]);
374246772Sjkim#else
375246772Sjkim			for (i=0;i<5;i++) {
376246772Sjkim				res = pmac->u[i];
377246772Sjkim				pmac->c[4*i+0]=(unsigned char)(res>>24);
378246772Sjkim				pmac->c[4*i+1]=(unsigned char)(res>>16);
379246772Sjkim				pmac->c[4*i+2]=(unsigned char)(res>>8);
380246772Sjkim				pmac->c[4*i+3]=(unsigned char)res;
381246772Sjkim			}
382246772Sjkim#endif
383246772Sjkim			len += SHA_DIGEST_LENGTH;
384246772Sjkim#else
385246772Sjkim			SHA1_Update(&key->md,out,inp_len);
386246772Sjkim			res = key->md.num;
387246772Sjkim			SHA1_Final(pmac->c,&key->md);
388246772Sjkim
389246772Sjkim			{
390246772Sjkim			unsigned int inp_blocks, pad_blocks;
391246772Sjkim
392246772Sjkim			/* but pretend as if we hashed padded payload */
393246772Sjkim			inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
394246772Sjkim			res += (unsigned int)(len-inp_len);
395246772Sjkim			pad_blocks = res / SHA_CBLOCK;
396246772Sjkim			res %= SHA_CBLOCK;
397246772Sjkim			pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
398246772Sjkim			for (;inp_blocks<pad_blocks;inp_blocks++)
399246772Sjkim				sha1_block_data_order(&key->md,data,1);
400246772Sjkim			}
401246772Sjkim#endif
402238384Sjkim			key->md = key->tail;
403246772Sjkim			SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH);
404246772Sjkim			SHA1_Final(pmac->c,&key->md);
405238384Sjkim
406246772Sjkim			/* verify HMAC */
407246772Sjkim			out += inp_len;
408246772Sjkim			len -= inp_len;
409246772Sjkim#if 1
410246772Sjkim			{
411246772Sjkim			unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH;
412246772Sjkim			size_t off = out-p;
413246772Sjkim			unsigned int c, cmask;
414246772Sjkim
415246772Sjkim			maxpad += SHA_DIGEST_LENGTH;
416246772Sjkim			for (res=0,i=0,j=0;j<maxpad;j++) {
417246772Sjkim				c = p[j];
418246772Sjkim				cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1);
419246772Sjkim				res |= (c^pad)&~cmask;	/* ... and padding */
420246772Sjkim				cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
421246772Sjkim				res |= (c^pmac->c[i])&cmask;
422246772Sjkim				i += 1&cmask;
423246772Sjkim			}
424246772Sjkim			maxpad -= SHA_DIGEST_LENGTH;
425246772Sjkim
426246772Sjkim			res = 0-((0-res)>>(sizeof(res)*8-1));
427246772Sjkim			ret &= (int)~res;
428246772Sjkim			}
429246772Sjkim#else
430246772Sjkim			for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
431246772Sjkim				res |= out[i]^pmac->c[i];
432246772Sjkim			res = 0-((0-res)>>(sizeof(res)*8-1));
433246772Sjkim			ret &= (int)~res;
434246772Sjkim
435246772Sjkim			/* verify padding */
436246772Sjkim			pad = (pad&~res) | (maxpad&res);
437246772Sjkim			out = out+len-1-pad;
438246772Sjkim			for (res=0,i=0;i<pad;i++)
439246772Sjkim				res |= out[i]^pad;
440246772Sjkim
441246772Sjkim			res = (0-res)>>(sizeof(res)*8-1);
442246772Sjkim			ret &= (int)~res;
443246772Sjkim#endif
444246772Sjkim			return ret;
445238384Sjkim		} else {
446238384Sjkim			SHA1_Update(&key->md,out,len);
447238384Sjkim		}
448238384Sjkim	}
449238384Sjkim
450238384Sjkim	return 1;
451238384Sjkim	}
452238384Sjkim
453238384Sjkimstatic int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
454238384Sjkim	{
455238384Sjkim	EVP_AES_HMAC_SHA1 *key = data(ctx);
456238384Sjkim
457238384Sjkim	switch (type)
458238384Sjkim		{
459238384Sjkim	case EVP_CTRL_AEAD_SET_MAC_KEY:
460238384Sjkim		{
461238384Sjkim		unsigned int  i;
462238384Sjkim		unsigned char hmac_key[64];
463238384Sjkim
464238384Sjkim		memset (hmac_key,0,sizeof(hmac_key));
465238384Sjkim
466238384Sjkim		if (arg > (int)sizeof(hmac_key)) {
467238384Sjkim			SHA1_Init(&key->head);
468238384Sjkim			SHA1_Update(&key->head,ptr,arg);
469238384Sjkim			SHA1_Final(hmac_key,&key->head);
470238384Sjkim		} else {
471238384Sjkim			memcpy(hmac_key,ptr,arg);
472238384Sjkim		}
473238384Sjkim
474238384Sjkim		for (i=0;i<sizeof(hmac_key);i++)
475238384Sjkim			hmac_key[i] ^= 0x36;		/* ipad */
476238384Sjkim		SHA1_Init(&key->head);
477238384Sjkim		SHA1_Update(&key->head,hmac_key,sizeof(hmac_key));
478238384Sjkim
479238384Sjkim		for (i=0;i<sizeof(hmac_key);i++)
480238384Sjkim			hmac_key[i] ^= 0x36^0x5c;	/* opad */
481238384Sjkim		SHA1_Init(&key->tail);
482238384Sjkim		SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
483238384Sjkim
484246772Sjkim		OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
485246772Sjkim
486238384Sjkim		return 1;
487238384Sjkim		}
488238384Sjkim	case EVP_CTRL_AEAD_TLS1_AAD:
489238384Sjkim		{
490238384Sjkim		unsigned char *p=ptr;
491238384Sjkim		unsigned int   len=p[arg-2]<<8|p[arg-1];
492238384Sjkim
493238384Sjkim		if (ctx->encrypt)
494238384Sjkim			{
495238384Sjkim			key->payload_length = len;
496238384Sjkim			if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
497238384Sjkim				len -= AES_BLOCK_SIZE;
498238384Sjkim				p[arg-2] = len>>8;
499238384Sjkim				p[arg-1] = len;
500238384Sjkim			}
501238384Sjkim			key->md = key->head;
502238384Sjkim			SHA1_Update(&key->md,p,arg);
503238384Sjkim
504238384Sjkim			return (int)(((len+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
505238384Sjkim				- len);
506238384Sjkim			}
507238384Sjkim		else
508238384Sjkim			{
509238384Sjkim			if (arg>13) arg = 13;
510238384Sjkim			memcpy(key->aux.tls_aad,ptr,arg);
511238384Sjkim			key->payload_length = arg;
512238384Sjkim
513238384Sjkim			return SHA_DIGEST_LENGTH;
514238384Sjkim			}
515238384Sjkim		}
516238384Sjkim	default:
517238384Sjkim		return -1;
518238384Sjkim		}
519238384Sjkim	}
520238384Sjkim
521238384Sjkimstatic EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher =
522238384Sjkim	{
523238384Sjkim#ifdef NID_aes_128_cbc_hmac_sha1
524238384Sjkim	NID_aes_128_cbc_hmac_sha1,
525238384Sjkim#else
526238384Sjkim	NID_undef,
527238384Sjkim#endif
528238384Sjkim	16,16,16,
529238384Sjkim	EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
530238384Sjkim	aesni_cbc_hmac_sha1_init_key,
531238384Sjkim	aesni_cbc_hmac_sha1_cipher,
532238384Sjkim	NULL,
533238384Sjkim	sizeof(EVP_AES_HMAC_SHA1),
534238384Sjkim	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
535238384Sjkim	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
536238384Sjkim	aesni_cbc_hmac_sha1_ctrl,
537238384Sjkim	NULL
538238384Sjkim	};
539238384Sjkim
540238384Sjkimstatic EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher =
541238384Sjkim	{
542238384Sjkim#ifdef NID_aes_256_cbc_hmac_sha1
543238384Sjkim	NID_aes_256_cbc_hmac_sha1,
544238384Sjkim#else
545238384Sjkim	NID_undef,
546238384Sjkim#endif
547238384Sjkim	16,32,16,
548238384Sjkim	EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
549238384Sjkim	aesni_cbc_hmac_sha1_init_key,
550238384Sjkim	aesni_cbc_hmac_sha1_cipher,
551238384Sjkim	NULL,
552238384Sjkim	sizeof(EVP_AES_HMAC_SHA1),
553238384Sjkim	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
554238384Sjkim	EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
555238384Sjkim	aesni_cbc_hmac_sha1_ctrl,
556238384Sjkim	NULL
557238384Sjkim	};
558238384Sjkim
559238384Sjkimconst EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
560238384Sjkim	{
561238384Sjkim	return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
562238384Sjkim		&aesni_128_cbc_hmac_sha1_cipher:NULL);
563238384Sjkim	}
564238384Sjkim
565238384Sjkimconst EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
566238384Sjkim	{
567238384Sjkim	return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
568238384Sjkim		&aesni_256_cbc_hmac_sha1_cipher:NULL);
569238384Sjkim	}
570238384Sjkim#else
571238384Sjkimconst EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
572238384Sjkim	{
573238384Sjkim	return NULL;
574238384Sjkim	}
575238384Sjkimconst EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
576238384Sjkim	{
577238384Sjkim	return NULL;
578238384Sjkim	}
579238384Sjkim#endif
580238384Sjkim#endif
581