OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
e_aes_cbc_hmac_sha1.c
Go to the documentation of this file.
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
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  {
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;
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 
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 
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 
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 
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 
277 
278  return 1;
279  }
280 
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  {
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  }
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
351 #else
352  NID_undef,
353 #endif
354  16,16,16,
356  aesni_cbc_hmac_sha1_init_key,
357  aesni_cbc_hmac_sha1_cipher,
358  NULL,
359  sizeof(EVP_AES_HMAC_SHA1),
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
370 #else
371  NID_undef,
372 #endif
373  16,32,16,
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 
386  {
387  return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
388  &aesni_128_cbc_hmac_sha1_cipher:NULL);
389  }
390 
392  {
393  return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
394  &aesni_256_cbc_hmac_sha1_cipher:NULL);
395  }
396 #else
398  {
399  return NULL;
400  }
402  {
403  return NULL;
404  }
405 #endif
406 #endif