1 /* ====================================================================
2 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
30 * 6. Redistributions of any form whatsoever must retain the following
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
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 * ====================================================================
50 #include <openssl/opensslconf.h>
55 #if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
57 #include <openssl/evp.h>
58 #include <openssl/objects.h>
59 #include <openssl/aes.h>
60 #include <openssl/sha.h>
62 #ifndef EVP_CIPH_FLAG_AEAD_CIPHER
63 #define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
64 #define EVP_CTRL_AEAD_TLS1_AAD 0x16
65 #define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
68 #if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
69 #define EVP_CIPH_FLAG_DEFAULT_ASN1 0
72 #define TLS1_1_VERSION 0x0302
78 size_t payload_length
; /* AAD length in decrypt case */
81 unsigned char tls_aad
[16]; /* 13 used */
85 #if defined(AES_ASM) && ( \
86 defined(__x86_64) || defined(__x86_64__) || \
87 defined(_M_AMD64) || defined(_M_X64) || \
90 extern unsigned int OPENSSL_ia32cap_P
[2];
91 #define AESNI_CAPABLE (1<<(57-32))
93 int aesni_set_encrypt_key(const unsigned char *userKey
, int bits
,
95 int aesni_set_decrypt_key(const unsigned char *userKey
, int bits
,
98 void aesni_cbc_encrypt(const unsigned char *in
,
102 unsigned char *ivec
, int enc
);
104 void aesni_cbc_sha1_enc (const void *inp
, void *out
, size_t blocks
,
105 const AES_KEY
*key
, unsigned char iv
[16],
106 SHA_CTX
*ctx
,const void *in0
);
108 #define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
110 static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX
*ctx
,
111 const unsigned char *inkey
,
112 const unsigned char *iv
, int enc
)
114 EVP_AES_HMAC_SHA1
*key
= data(ctx
);
118 ret
=aesni_set_encrypt_key(inkey
,ctx
->key_len
*8,&key
->ks
);
120 ret
=aesni_set_decrypt_key(inkey
,ctx
->key_len
*8,&key
->ks
);
122 SHA1_Init(&key
->head
); /* handy when benchmarking */
123 key
->tail
= key
->head
;
126 key
->payload_length
= 0;
131 #define STITCHED_CALL
133 #if !defined(STITCHED_CALL)
137 void sha1_block_data_order (void *c
,const void *p
,size_t len
);
139 static void sha1_update(SHA_CTX
*c
,const void *data
,size_t len
)
140 { const unsigned char *ptr
= data
;
143 if ((res
= c
->num
)) {
144 res
= SHA_CBLOCK
-res
;
145 if (len
<res
) res
=len
;
146 SHA1_Update (c
,ptr
,res
);
151 res
= len
% SHA_CBLOCK
;
155 sha1_block_data_order(c
,ptr
,len
/SHA_CBLOCK
);
160 if (c
->Nl
<(unsigned int)len
) c
->Nh
++;
164 SHA1_Update(c
,ptr
,res
);
167 #define SHA1_Update sha1_update
169 static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX
*ctx
, unsigned char *out
,
170 const unsigned char *in
, size_t len
)
172 EVP_AES_HMAC_SHA1
*key
= data(ctx
);
174 size_t plen
= key
->payload_length
,
175 iv
= 0, /* explicit IV in TLS 1.1 and later */
177 #if defined(STITCHED_CALL)
181 sha_off
= SHA_CBLOCK
-key
->md
.num
;
184 if (len
%AES_BLOCK_SIZE
) return 0;
189 else if (len
!=((plen
+SHA_DIGEST_LENGTH
+AES_BLOCK_SIZE
)&-AES_BLOCK_SIZE
))
191 else if (key
->aux
.tls_ver
>= TLS1_1_VERSION
)
194 #if defined(STITCHED_CALL)
195 if (plen
>(sha_off
+iv
) && (blocks
=(plen
-(sha_off
+iv
))/SHA_CBLOCK
)) {
196 SHA1_Update(&key
->md
,in
+iv
,sha_off
);
198 aesni_cbc_sha1_enc(in
,out
,blocks
,&key
->ks
,
199 ctx
->iv
,&key
->md
,in
+iv
+sha_off
);
200 blocks
*= SHA_CBLOCK
;
203 key
->md
.Nh
+= blocks
>>29;
204 key
->md
.Nl
+= blocks
<<=3;
205 if (key
->md
.Nl
<(unsigned int)blocks
) key
->md
.Nh
++;
211 SHA1_Update(&key
->md
,in
+sha_off
,plen
-sha_off
);
213 if (plen
!=len
) { /* "TLS" mode of operation */
215 memcpy(out
+aes_off
,in
+aes_off
,plen
-aes_off
);
217 /* calculate HMAC and append it to payload */
218 SHA1_Final(out
+plen
,&key
->md
);
220 SHA1_Update(&key
->md
,out
+plen
,SHA_DIGEST_LENGTH
);
221 SHA1_Final(out
+plen
,&key
->md
);
223 /* pad the payload|hmac */
224 plen
+= SHA_DIGEST_LENGTH
;
225 for (l
=len
-plen
-1;plen
<len
;plen
++) out
[plen
]=l
;
226 /* encrypt HMAC|padding at once */
227 aesni_cbc_encrypt(out
+aes_off
,out
+aes_off
,len
-aes_off
,
230 aesni_cbc_encrypt(in
+aes_off
,out
+aes_off
,len
-aes_off
,
234 unsigned char mac
[SHA_DIGEST_LENGTH
];
236 /* decrypt HMAC|padding at once */
237 aesni_cbc_encrypt(in
,out
,len
,
240 if (plen
) { /* "TLS" mode of operation */
241 /* figure out payload length */
242 if (len
<(out
[len
-1]+1+SHA_DIGEST_LENGTH
))
245 len
-= (out
[len
-1]+1+SHA_DIGEST_LENGTH
);
247 if ((key
->aux
.tls_aad
[plen
-4]<<8|key
->aux
.tls_aad
[plen
-3])
249 len
-= AES_BLOCK_SIZE
;
253 key
->aux
.tls_aad
[plen
-2] = len
>>8;
254 key
->aux
.tls_aad
[plen
-1] = len
;
256 /* calculate HMAC and verify it */
258 SHA1_Update(&key
->md
,key
->aux
.tls_aad
,plen
);
259 SHA1_Update(&key
->md
,out
+iv
,len
);
260 SHA1_Final(mac
,&key
->md
);
263 SHA1_Update(&key
->md
,mac
,SHA_DIGEST_LENGTH
);
264 SHA1_Final(mac
,&key
->md
);
266 if (memcmp(out
+iv
+len
,mac
,SHA_DIGEST_LENGTH
))
269 SHA1_Update(&key
->md
,out
,len
);
273 key
->payload_length
= 0;
278 static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX
*ctx
, int type
, int arg
, void *ptr
)
280 EVP_AES_HMAC_SHA1
*key
= data(ctx
);
284 case EVP_CTRL_AEAD_SET_MAC_KEY
:
287 unsigned char hmac_key
[64];
289 memset (hmac_key
,0,sizeof(hmac_key
));
291 if (arg
> sizeof(hmac_key
)) {
292 SHA1_Init(&key
->head
);
293 SHA1_Update(&key
->head
,ptr
,arg
);
294 SHA1_Final(hmac_key
,&key
->head
);
296 memcpy(hmac_key
,ptr
,arg
);
299 for (i
=0;i
<sizeof(hmac_key
);i
++)
300 hmac_key
[i
] ^= 0x36; /* ipad */
301 SHA1_Init(&key
->head
);
302 SHA1_Update(&key
->head
,hmac_key
,sizeof(hmac_key
));
304 for (i
=0;i
<sizeof(hmac_key
);i
++)
305 hmac_key
[i
] ^= 0x36^0x5c; /* opad */
306 SHA1_Init(&key
->tail
);
307 SHA1_Update(&key
->tail
,hmac_key
,sizeof(hmac_key
));
311 case EVP_CTRL_AEAD_TLS1_AAD
:
313 unsigned char *p
=ptr
;
314 unsigned int len
=p
[arg
-2]<<8|p
[arg
-1];
318 key
->payload_length
= len
;
319 if ((key
->aux
.tls_ver
=p
[arg
-4]<<8|p
[arg
-3]) >= TLS1_1_VERSION
) {
320 len
-= AES_BLOCK_SIZE
;
325 SHA1_Update(&key
->md
,p
,arg
);
327 return (int)(((len
+SHA_DIGEST_LENGTH
+AES_BLOCK_SIZE
)&-AES_BLOCK_SIZE
)
332 if (arg
>13) arg
= 13;
333 memcpy(key
->aux
.tls_aad
,ptr
,arg
);
334 key
->payload_length
= arg
;
336 return SHA_DIGEST_LENGTH
;
344 static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher
=
346 #ifdef NID_aes_128_cbc_hmac_sha1
347 NID_aes_128_cbc_hmac_sha1
,
352 EVP_CIPH_CBC_MODE
|EVP_CIPH_FLAG_DEFAULT_ASN1
|EVP_CIPH_FLAG_AEAD_CIPHER
,
353 aesni_cbc_hmac_sha1_init_key
,
354 aesni_cbc_hmac_sha1_cipher
,
356 sizeof(EVP_AES_HMAC_SHA1
),
357 EVP_CIPH_FLAG_DEFAULT_ASN1
?NULL
:EVP_CIPHER_set_asn1_iv
,
358 EVP_CIPH_FLAG_DEFAULT_ASN1
?NULL
:EVP_CIPHER_get_asn1_iv
,
359 aesni_cbc_hmac_sha1_ctrl
,
363 static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher
=
365 #ifdef NID_aes_256_cbc_hmac_sha1
366 NID_aes_256_cbc_hmac_sha1
,
371 EVP_CIPH_CBC_MODE
|EVP_CIPH_FLAG_DEFAULT_ASN1
|EVP_CIPH_FLAG_AEAD_CIPHER
,
372 aesni_cbc_hmac_sha1_init_key
,
373 aesni_cbc_hmac_sha1_cipher
,
375 sizeof(EVP_AES_HMAC_SHA1
),
376 EVP_CIPH_FLAG_DEFAULT_ASN1
?NULL
:EVP_CIPHER_set_asn1_iv
,
377 EVP_CIPH_FLAG_DEFAULT_ASN1
?NULL
:EVP_CIPHER_get_asn1_iv
,
378 aesni_cbc_hmac_sha1_ctrl
,
382 const EVP_CIPHER
*EVP_aes_128_cbc_hmac_sha1(void)
384 return(OPENSSL_ia32cap_P
[1]&AESNI_CAPABLE
?
385 &aesni_128_cbc_hmac_sha1_cipher
:NULL
);
388 const EVP_CIPHER
*EVP_aes_256_cbc_hmac_sha1(void)
390 return(OPENSSL_ia32cap_P
[1]&AESNI_CAPABLE
?
391 &aesni_256_cbc_hmac_sha1_cipher
:NULL
);
394 const EVP_CIPHER
*EVP_aes_128_cbc_hmac_sha1(void)
398 const EVP_CIPHER
*EVP_aes_256_cbc_hmac_sha1(void)