e_aes_cbc_hmac_sha1.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  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. #include <openssl/opensslconf.h>
  50. #include <stdio.h>
  51. #include <string.h>
  52. #if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
  53. #include <openssl/evp.h>
  54. #include <openssl/objects.h>
  55. #include <openssl/aes.h>
  56. #include <openssl/sha.h>
  57. #ifndef EVP_CIPH_FLAG_AEAD_CIPHER
  58. #define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
  59. #define EVP_CTRL_AEAD_TLS1_AAD 0x16
  60. #define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
  61. #endif
  62. #if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
  63. #define EVP_CIPH_FLAG_DEFAULT_ASN1 0
  64. #endif
  65. #define TLS1_1_VERSION 0x0302
  66. typedef struct
  67. {
  68. AES_KEY ks;
  69. SHA_CTX head,tail,md;
  70. size_t payload_length; /* AAD length in decrypt case */
  71. union {
  72. unsigned int tls_ver;
  73. unsigned char tls_aad[16]; /* 13 used */
  74. } aux;
  75. } EVP_AES_HMAC_SHA1;
  76. #if defined(AES_ASM) && ( \
  77. defined(__x86_64) || defined(__x86_64__) || \
  78. defined(_M_AMD64) || defined(_M_X64) || \
  79. defined(__INTEL__) )
  80. extern unsigned int OPENSSL_ia32cap_P[2];
  81. #define AESNI_CAPABLE (1<<(57-32))
  82. int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
  83. AES_KEY *key);
  84. int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
  85. AES_KEY *key);
  86. void aesni_cbc_encrypt(const unsigned char *in,
  87. unsigned char *out,
  88. size_t length,
  89. const AES_KEY *key,
  90. unsigned char *ivec, int enc);
  91. void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
  92. const AES_KEY *key, unsigned char iv[16],
  93. SHA_CTX *ctx,const void *in0);
  94. #define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
  95. static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
  96. const unsigned char *inkey,
  97. const unsigned char *iv, int enc)
  98. {
  99. EVP_AES_HMAC_SHA1 *key = data(ctx);
  100. int ret;
  101. if (enc)
  102. ret=aesni_set_encrypt_key(inkey,ctx->key_len*8,&key->ks);
  103. else
  104. ret=aesni_set_decrypt_key(inkey,ctx->key_len*8,&key->ks);
  105. SHA1_Init(&key->head); /* handy when benchmarking */
  106. key->tail = key->head;
  107. key->md = key->head;
  108. key->payload_length = 0;
  109. return ret<0?0:1;
  110. }
  111. #define STITCHED_CALL
  112. #if !defined(STITCHED_CALL)
  113. #define aes_off 0
  114. #endif
  115. void sha1_block_data_order (void *c,const void *p,size_t len);
  116. static void sha1_update(SHA_CTX *c,const void *data,size_t len)
  117. { const unsigned char *ptr = data;
  118. size_t res;
  119. if ((res = c->num)) {
  120. res = SHA_CBLOCK-res;
  121. if (len<res) res=len;
  122. SHA1_Update (c,ptr,res);
  123. ptr += res;
  124. len -= res;
  125. }
  126. res = len % SHA_CBLOCK;
  127. len -= res;
  128. if (len) {
  129. sha1_block_data_order(c,ptr,len/SHA_CBLOCK);
  130. ptr += len;
  131. c->Nh += len>>29;
  132. c->Nl += len<<=3;
  133. if (c->Nl<(unsigned int)len) c->Nh++;
  134. }
  135. if (res)
  136. SHA1_Update(c,ptr,res);
  137. }
  138. #define SHA1_Update sha1_update
  139. static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
  140. const unsigned char *in, size_t len)
  141. {
  142. EVP_AES_HMAC_SHA1 *key = data(ctx);
  143. unsigned int l;
  144. size_t plen = key->payload_length,
  145. iv = 0, /* explicit IV in TLS 1.1 and later */
  146. sha_off = 0;
  147. #if defined(STITCHED_CALL)
  148. size_t aes_off = 0,
  149. blocks;
  150. sha_off = SHA_CBLOCK-key->md.num;
  151. #endif
  152. if (len%AES_BLOCK_SIZE) return 0;
  153. if (ctx->encrypt) {
  154. if (plen==0)
  155. plen = len;
  156. else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
  157. return 0;
  158. else if (key->aux.tls_ver >= TLS1_1_VERSION)
  159. iv = AES_BLOCK_SIZE;
  160. #if defined(STITCHED_CALL)
  161. if (plen>(sha_off+iv) && (blocks=(plen-(sha_off+iv))/SHA_CBLOCK)) {
  162. SHA1_Update(&key->md,in+iv,sha_off);
  163. aesni_cbc_sha1_enc(in,out,blocks,&key->ks,
  164. ctx->iv,&key->md,in+iv+sha_off);
  165. blocks *= SHA_CBLOCK;
  166. aes_off += blocks;
  167. sha_off += blocks;
  168. key->md.Nh += blocks>>29;
  169. key->md.Nl += blocks<<=3;
  170. if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
  171. } else {
  172. sha_off = 0;
  173. }
  174. #endif
  175. sha_off += iv;
  176. SHA1_Update(&key->md,in+sha_off,plen-sha_off);
  177. if (plen!=len) { /* "TLS" mode of operation */
  178. if (in!=out)
  179. memcpy(out+aes_off,in+aes_off,plen-aes_off);
  180. /* calculate HMAC and append it to payload */
  181. SHA1_Final(out+plen,&key->md);
  182. key->md = key->tail;
  183. SHA1_Update(&key->md,out+plen,SHA_DIGEST_LENGTH);
  184. SHA1_Final(out+plen,&key->md);
  185. /* pad the payload|hmac */
  186. plen += SHA_DIGEST_LENGTH;
  187. for (l=len-plen-1;plen<len;plen++) out[plen]=l;
  188. /* encrypt HMAC|padding at once */
  189. aesni_cbc_encrypt(out+aes_off,out+aes_off,len-aes_off,
  190. &key->ks,ctx->iv,1);
  191. } else {
  192. aesni_cbc_encrypt(in+aes_off,out+aes_off,len-aes_off,
  193. &key->ks,ctx->iv,1);
  194. }
  195. } else {
  196. unsigned char mac[SHA_DIGEST_LENGTH];
  197. /* decrypt HMAC|padding at once */
  198. aesni_cbc_encrypt(in,out,len,
  199. &key->ks,ctx->iv,0);
  200. if (plen) { /* "TLS" mode of operation */
  201. /* figure out payload length */
  202. if (len<(size_t)(out[len-1]+1+SHA_DIGEST_LENGTH))
  203. return 0;
  204. len -= (out[len-1]+1+SHA_DIGEST_LENGTH);
  205. if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
  206. >= TLS1_1_VERSION) {
  207. len -= AES_BLOCK_SIZE;
  208. iv = AES_BLOCK_SIZE;
  209. }
  210. key->aux.tls_aad[plen-2] = len>>8;
  211. key->aux.tls_aad[plen-1] = len;
  212. /* calculate HMAC and verify it */
  213. key->md = key->head;
  214. SHA1_Update(&key->md,key->aux.tls_aad,plen);
  215. SHA1_Update(&key->md,out+iv,len);
  216. SHA1_Final(mac,&key->md);
  217. key->md = key->tail;
  218. SHA1_Update(&key->md,mac,SHA_DIGEST_LENGTH);
  219. SHA1_Final(mac,&key->md);
  220. if (memcmp(out+iv+len,mac,SHA_DIGEST_LENGTH))
  221. return 0;
  222. } else {
  223. SHA1_Update(&key->md,out,len);
  224. }
  225. }
  226. key->payload_length = 0;
  227. return 1;
  228. }
  229. static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
  230. {
  231. EVP_AES_HMAC_SHA1 *key = data(ctx);
  232. switch (type)
  233. {
  234. case EVP_CTRL_AEAD_SET_MAC_KEY:
  235. {
  236. unsigned int i;
  237. unsigned char hmac_key[64];
  238. memset (hmac_key,0,sizeof(hmac_key));
  239. if (arg > (int)sizeof(hmac_key)) {
  240. SHA1_Init(&key->head);
  241. SHA1_Update(&key->head,ptr,arg);
  242. SHA1_Final(hmac_key,&key->head);
  243. } else {
  244. memcpy(hmac_key,ptr,arg);
  245. }
  246. for (i=0;i<sizeof(hmac_key);i++)
  247. hmac_key[i] ^= 0x36; /* ipad */
  248. SHA1_Init(&key->head);
  249. SHA1_Update(&key->head,hmac_key,sizeof(hmac_key));
  250. for (i=0;i<sizeof(hmac_key);i++)
  251. hmac_key[i] ^= 0x36^0x5c; /* opad */
  252. SHA1_Init(&key->tail);
  253. SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
  254. return 1;
  255. }
  256. case EVP_CTRL_AEAD_TLS1_AAD:
  257. {
  258. unsigned char *p=ptr;
  259. unsigned int len=p[arg-2]<<8|p[arg-1];
  260. if (ctx->encrypt)
  261. {
  262. key->payload_length = len;
  263. if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
  264. len -= AES_BLOCK_SIZE;
  265. p[arg-2] = len>>8;
  266. p[arg-1] = len;
  267. }
  268. key->md = key->head;
  269. SHA1_Update(&key->md,p,arg);
  270. return (int)(((len+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
  271. - len);
  272. }
  273. else
  274. {
  275. if (arg>13) arg = 13;
  276. memcpy(key->aux.tls_aad,ptr,arg);
  277. key->payload_length = arg;
  278. return SHA_DIGEST_LENGTH;
  279. }
  280. }
  281. default:
  282. return -1;
  283. }
  284. }
  285. static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher =
  286. {
  287. #ifdef NID_aes_128_cbc_hmac_sha1
  288. NID_aes_128_cbc_hmac_sha1,
  289. #else
  290. NID_undef,
  291. #endif
  292. 16,16,16,
  293. EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
  294. aesni_cbc_hmac_sha1_init_key,
  295. aesni_cbc_hmac_sha1_cipher,
  296. NULL,
  297. sizeof(EVP_AES_HMAC_SHA1),
  298. EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
  299. EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
  300. aesni_cbc_hmac_sha1_ctrl,
  301. NULL
  302. };
  303. static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher =
  304. {
  305. #ifdef NID_aes_256_cbc_hmac_sha1
  306. NID_aes_256_cbc_hmac_sha1,
  307. #else
  308. NID_undef,
  309. #endif
  310. 16,32,16,
  311. EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
  312. aesni_cbc_hmac_sha1_init_key,
  313. aesni_cbc_hmac_sha1_cipher,
  314. NULL,
  315. sizeof(EVP_AES_HMAC_SHA1),
  316. EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
  317. EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
  318. aesni_cbc_hmac_sha1_ctrl,
  319. NULL
  320. };
  321. const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
  322. {
  323. return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
  324. &aesni_128_cbc_hmac_sha1_cipher:NULL);
  325. }
  326. const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
  327. {
  328. return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
  329. &aesni_256_cbc_hmac_sha1_cipher:NULL);
  330. }
  331. #else
  332. const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
  333. {
  334. return NULL;
  335. }
  336. const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
  337. {
  338. return NULL;
  339. }
  340. #endif
  341. #endif