Import OpenSSL-1.0.1.
[dragonfly.git] / crypto / openssl / crypto / evp / e_aes_cbc_hmac_sha1.c
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 #if     defined(AES_ASM) &&     ( \
87         defined(__x86_64)       || defined(__x86_64__)  || \
88         defined(_M_AMD64)       || defined(_M_X64)      || \
89         defined(__INTEL__)      )
90
91 extern unsigned int OPENSSL_ia32cap_P[2];
92 #define AESNI_CAPABLE   (1<<(57-32))
93
94 int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
95                               AES_KEY *key);
96 int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
97                               AES_KEY *key);
98
99 void aesni_cbc_encrypt(const unsigned char *in,
100                            unsigned char *out,
101                            size_t length,
102                            const AES_KEY *key,
103                            unsigned char *ivec, int enc);
104
105 void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
106                 const AES_KEY *key, unsigned char iv[16],
107                 SHA_CTX *ctx,const void *in0);
108
109 #define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
110
111 static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
112                         const unsigned char *inkey,
113                         const unsigned char *iv, int enc)
114         {
115         EVP_AES_HMAC_SHA1 *key = data(ctx);
116         int ret;
117
118         if (enc)
119                 ret=aesni_set_encrypt_key(inkey,ctx->key_len*8,&key->ks);
120         else
121                 ret=aesni_set_decrypt_key(inkey,ctx->key_len*8,&key->ks);
122
123         SHA1_Init(&key->head);  /* handy when benchmarking */
124         key->tail = key->head;
125         key->md   = key->head;
126
127         key->payload_length = 0;
128
129         return ret<0?0:1;
130         }
131
132 #define STITCHED_CALL
133
134 #if !defined(STITCHED_CALL)
135 #define aes_off 0
136 #endif
137
138 void sha1_block_data_order (void *c,const void *p,size_t len);
139
140 static void sha1_update(SHA_CTX *c,const void *data,size_t len)
141 {       const unsigned char *ptr = data;
142         size_t res;
143
144         if ((res = c->num)) {
145                 res = SHA_CBLOCK-res;
146                 if (len<res) res=len;
147                 SHA1_Update (c,ptr,res);
148                 ptr += res;
149                 len -= res;
150         }
151
152         res = len % SHA_CBLOCK;
153         len -= res;
154
155         if (len) {
156                 sha1_block_data_order(c,ptr,len/SHA_CBLOCK);
157
158                 ptr += len;
159                 c->Nh += len>>29;
160                 c->Nl += len<<=3;
161                 if (c->Nl<(unsigned int)len) c->Nh++;
162         }
163
164         if (res)
165                 SHA1_Update(c,ptr,res);
166 }
167
168 #define SHA1_Update sha1_update
169
170 static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
171                       const unsigned char *in, size_t len)
172         {
173         EVP_AES_HMAC_SHA1 *key = data(ctx);
174         unsigned int l;
175         size_t  plen = key->payload_length,
176                 iv = 0,         /* explicit IV in TLS 1.1 and later */
177                 sha_off = 0;
178 #if defined(STITCHED_CALL)
179         size_t  aes_off = 0,
180                 blocks;
181
182         sha_off = SHA_CBLOCK-key->md.num;
183 #endif
184
185         if (len%AES_BLOCK_SIZE) return 0;
186
187         if (ctx->encrypt) {
188                 if (plen==0)
189                         plen = len;
190                 else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
191                         return 0;
192                 else if (key->aux.tls_ver >= TLS1_1_VERSION)
193                         iv = AES_BLOCK_SIZE;
194
195 #if defined(STITCHED_CALL)
196                 if (plen>(sha_off+iv) && (blocks=(plen-(sha_off+iv))/SHA_CBLOCK)) {
197                         SHA1_Update(&key->md,in+iv,sha_off);
198
199                         aesni_cbc_sha1_enc(in,out,blocks,&key->ks,
200                                 ctx->iv,&key->md,in+iv+sha_off);
201                         blocks *= SHA_CBLOCK;
202                         aes_off += blocks;
203                         sha_off += blocks;
204                         key->md.Nh += blocks>>29;
205                         key->md.Nl += blocks<<=3;
206                         if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
207                 } else {
208                         sha_off = 0;
209                 }
210 #endif
211                 sha_off += iv;
212                 SHA1_Update(&key->md,in+sha_off,plen-sha_off);
213
214                 if (plen!=len)  {       /* "TLS" mode of operation */
215                         if (in!=out)
216                                 memcpy(out+aes_off,in+aes_off,plen-aes_off);
217
218                         /* calculate HMAC and append it to payload */
219                         SHA1_Final(out+plen,&key->md);
220                         key->md = key->tail;
221                         SHA1_Update(&key->md,out+plen,SHA_DIGEST_LENGTH);
222                         SHA1_Final(out+plen,&key->md);
223
224                         /* pad the payload|hmac */
225                         plen += SHA_DIGEST_LENGTH;
226                         for (l=len-plen-1;plen<len;plen++) out[plen]=l;
227                         /* encrypt HMAC|padding at once */
228                         aesni_cbc_encrypt(out+aes_off,out+aes_off,len-aes_off,
229                                         &key->ks,ctx->iv,1);
230                 } else {
231                         aesni_cbc_encrypt(in+aes_off,out+aes_off,len-aes_off,
232                                         &key->ks,ctx->iv,1);
233                 }
234         } else {
235                 unsigned char mac[SHA_DIGEST_LENGTH];
236
237                 /* decrypt HMAC|padding at once */
238                 aesni_cbc_encrypt(in,out,len,
239                                 &key->ks,ctx->iv,0);
240
241                 if (plen) {     /* "TLS" mode of operation */
242                         /* figure out payload length */
243                         if (len<(size_t)(out[len-1]+1+SHA_DIGEST_LENGTH))
244                                 return 0;
245
246                         len -= (out[len-1]+1+SHA_DIGEST_LENGTH);
247
248                         if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
249                             >= TLS1_1_VERSION) {
250                                 len -= AES_BLOCK_SIZE;
251                                 iv = AES_BLOCK_SIZE;
252                         }
253
254                         key->aux.tls_aad[plen-2] = len>>8;
255                         key->aux.tls_aad[plen-1] = len;
256
257                         /* calculate HMAC and verify it */
258                         key->md = key->head;
259                         SHA1_Update(&key->md,key->aux.tls_aad,plen);
260                         SHA1_Update(&key->md,out+iv,len);
261                         SHA1_Final(mac,&key->md);
262
263                         key->md = key->tail;
264                         SHA1_Update(&key->md,mac,SHA_DIGEST_LENGTH);
265                         SHA1_Final(mac,&key->md);
266
267                         if (memcmp(out+iv+len,mac,SHA_DIGEST_LENGTH))
268                                 return 0;
269                 } else {
270                         SHA1_Update(&key->md,out,len);
271                 }
272         }
273
274         key->payload_length = 0;
275
276         return 1;
277         }
278
279 static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
280         {
281         EVP_AES_HMAC_SHA1 *key = data(ctx);
282
283         switch (type)
284                 {
285         case EVP_CTRL_AEAD_SET_MAC_KEY:
286                 {
287                 unsigned int  i;
288                 unsigned char hmac_key[64];
289
290                 memset (hmac_key,0,sizeof(hmac_key));
291
292                 if (arg > (int)sizeof(hmac_key)) {
293                         SHA1_Init(&key->head);
294                         SHA1_Update(&key->head,ptr,arg);
295                         SHA1_Final(hmac_key,&key->head);
296                 } else {
297                         memcpy(hmac_key,ptr,arg);
298                 }
299
300                 for (i=0;i<sizeof(hmac_key);i++)
301                         hmac_key[i] ^= 0x36;            /* ipad */
302                 SHA1_Init(&key->head);
303                 SHA1_Update(&key->head,hmac_key,sizeof(hmac_key));
304
305                 for (i=0;i<sizeof(hmac_key);i++)
306                         hmac_key[i] ^= 0x36^0x5c;       /* opad */
307                 SHA1_Init(&key->tail);
308                 SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
309
310                 return 1;
311                 }
312         case EVP_CTRL_AEAD_TLS1_AAD:
313                 {
314                 unsigned char *p=ptr;
315                 unsigned int   len=p[arg-2]<<8|p[arg-1];
316
317                 if (ctx->encrypt)
318                         {
319                         key->payload_length = len;
320                         if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
321                                 len -= AES_BLOCK_SIZE;
322                                 p[arg-2] = len>>8;
323                                 p[arg-1] = len;
324                         }
325                         key->md = key->head;
326                         SHA1_Update(&key->md,p,arg);
327
328                         return (int)(((len+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
329                                 - len);
330                         }
331                 else
332                         {
333                         if (arg>13) arg = 13;
334                         memcpy(key->aux.tls_aad,ptr,arg);
335                         key->payload_length = arg;
336
337                         return SHA_DIGEST_LENGTH;
338                         }
339                 }
340         default:
341                 return -1;
342                 }
343         }
344
345 static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher =
346         {
347 #ifdef NID_aes_128_cbc_hmac_sha1
348         NID_aes_128_cbc_hmac_sha1,
349 #else
350         NID_undef,
351 #endif
352         16,16,16,
353         EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
354         aesni_cbc_hmac_sha1_init_key,
355         aesni_cbc_hmac_sha1_cipher,
356         NULL,
357         sizeof(EVP_AES_HMAC_SHA1),
358         EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
359         EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
360         aesni_cbc_hmac_sha1_ctrl,
361         NULL
362         };
363
364 static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher =
365         {
366 #ifdef NID_aes_256_cbc_hmac_sha1
367         NID_aes_256_cbc_hmac_sha1,
368 #else
369         NID_undef,
370 #endif
371         16,32,16,
372         EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
373         aesni_cbc_hmac_sha1_init_key,
374         aesni_cbc_hmac_sha1_cipher,
375         NULL,
376         sizeof(EVP_AES_HMAC_SHA1),
377         EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
378         EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
379         aesni_cbc_hmac_sha1_ctrl,
380         NULL
381         };
382
383 const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
384         {
385         return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
386                 &aesni_128_cbc_hmac_sha1_cipher:NULL);
387         }
388
389 const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
390         {
391         return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
392                 &aesni_256_cbc_hmac_sha1_cipher:NULL);
393         }
394 #else
395 const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
396         {
397         return NULL;
398         }
399 const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
400         {
401         return NULL;
402         }
403 #endif
404 #endif