- pmac->u[0]=0;
- pmac->u[1]=0;
- pmac->u[2]=0;
- pmac->u[3]=0;
- pmac->u[4]=0;
- pmac->u[5]=0;
- pmac->u[6]=0;
- pmac->u[7]=0;
-
- for (res=key->md.num, j=0;j<len;j++) {
- size_t c = out[j];
- mask = (j-inp_len)>>(sizeof(j)*8-8);
- c &= mask;
- c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
- data->c[res++]=(unsigned char)c;
-
- if (res!=SHA256_CBLOCK) continue;
-
- /* j is not incremented yet */
- mask = 0-((inp_len+7-j)>>(sizeof(j)*8-1));
- data->u[SHA_LBLOCK-1] |= bitlen&mask;
- sha256_block_data_order(&key->md,data,1);
- mask &= 0-((j-inp_len-72)>>(sizeof(j)*8-1));
- pmac->u[0] |= key->md.h[0] & mask;
- pmac->u[1] |= key->md.h[1] & mask;
- pmac->u[2] |= key->md.h[2] & mask;
- pmac->u[3] |= key->md.h[3] & mask;
- pmac->u[4] |= key->md.h[4] & mask;
- pmac->u[5] |= key->md.h[5] & mask;
- pmac->u[6] |= key->md.h[6] & mask;
- pmac->u[7] |= key->md.h[7] & mask;
- res=0;
- }
-
- for(i=res;i<SHA256_CBLOCK;i++,j++) data->c[i]=0;
-
- if (res>SHA256_CBLOCK-8) {
- mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
- data->u[SHA_LBLOCK-1] |= bitlen&mask;
- sha256_block_data_order(&key->md,data,1);
- mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
- pmac->u[0] |= key->md.h[0] & mask;
- pmac->u[1] |= key->md.h[1] & mask;
- pmac->u[2] |= key->md.h[2] & mask;
- pmac->u[3] |= key->md.h[3] & mask;
- pmac->u[4] |= key->md.h[4] & mask;
- pmac->u[5] |= key->md.h[5] & mask;
- pmac->u[6] |= key->md.h[6] & mask;
- pmac->u[7] |= key->md.h[7] & mask;
-
- memset(data,0,SHA256_CBLOCK);
- j+=64;
- }
- data->u[SHA_LBLOCK-1] = bitlen;
- sha256_block_data_order(&key->md,data,1);
- mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
- pmac->u[0] |= key->md.h[0] & mask;
- pmac->u[1] |= key->md.h[1] & mask;
- pmac->u[2] |= key->md.h[2] & mask;
- pmac->u[3] |= key->md.h[3] & mask;
- pmac->u[4] |= key->md.h[4] & mask;
- pmac->u[5] |= key->md.h[5] & mask;
- pmac->u[6] |= key->md.h[6] & mask;
- pmac->u[7] |= key->md.h[7] & mask;
-
-#ifdef BSWAP4
- pmac->u[0] = BSWAP4(pmac->u[0]);
- pmac->u[1] = BSWAP4(pmac->u[1]);
- pmac->u[2] = BSWAP4(pmac->u[2]);
- pmac->u[3] = BSWAP4(pmac->u[3]);
- pmac->u[4] = BSWAP4(pmac->u[4]);
- pmac->u[5] = BSWAP4(pmac->u[5]);
- pmac->u[6] = BSWAP4(pmac->u[6]);
- pmac->u[7] = BSWAP4(pmac->u[7]);
-#else
- for (i=0;i<8;i++) {
- res = pmac->u[i];
- pmac->c[4*i+0]=(unsigned char)(res>>24);
- pmac->c[4*i+1]=(unsigned char)(res>>16);
- pmac->c[4*i+2]=(unsigned char)(res>>8);
- pmac->c[4*i+3]=(unsigned char)res;
- }
-#endif
- len += SHA256_DIGEST_LENGTH;
-#else
- SHA256_Update(&key->md,out,inp_len);
- res = key->md.num;
- SHA256_Final(pmac->c,&key->md);
-
- {
- unsigned int inp_blocks, pad_blocks;
-
- /* but pretend as if we hashed padded payload */
- inp_blocks = 1+((SHA256_CBLOCK-9-res)>>(sizeof(res)*8-1));
- res += (unsigned int)(len-inp_len);
- pad_blocks = res / SHA256_CBLOCK;
- res %= SHA256_CBLOCK;
- pad_blocks += 1+((SHA256_CBLOCK-9-res)>>(sizeof(res)*8-1));
- for (;inp_blocks<pad_blocks;inp_blocks++)
- sha1_block_data_order(&key->md,data,1);
- }
-#endif
- key->md = key->tail;
- SHA256_Update(&key->md,pmac->c,SHA256_DIGEST_LENGTH);
- SHA256_Final(pmac->c,&key->md);
-
- /* verify HMAC */
- out += inp_len;
- len -= inp_len;
-#if 1
- {
- unsigned char *p = out+len-1-maxpad-SHA256_DIGEST_LENGTH;
- size_t off = out-p;
- unsigned int c, cmask;
-
- maxpad += SHA256_DIGEST_LENGTH;
- for (res=0,i=0,j=0;j<maxpad;j++) {
- c = p[j];
- cmask = ((int)(j-off-SHA256_DIGEST_LENGTH))>>(sizeof(int)*8-1);
- res |= (c^pad)&~cmask; /* ... and padding */
- cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
- res |= (c^pmac->c[i])&cmask;
- i += 1&cmask;
- }
- maxpad -= SHA256_DIGEST_LENGTH;
-
- res = 0-((0-res)>>(sizeof(res)*8-1));
- ret &= (int)~res;
- }
-#else
- for (res=0,i=0;i<SHA256_DIGEST_LENGTH;i++)
- res |= out[i]^pmac->c[i];
- res = 0-((0-res)>>(sizeof(res)*8-1));
- ret &= (int)~res;
-
- /* verify padding */
- pad = (pad&~res) | (maxpad&res);
- out = out+len-1-pad;
- for (res=0,i=0;i<pad;i++)
- res |= out[i]^pad;
-
- res = (0-res)>>(sizeof(res)*8-1);
- ret &= (int)~res;
-#endif
- return ret;
- } else {
- SHA256_Update(&key->md,out,len);
- }
- }
-
- return 1;
- }
-
-static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
- {
- EVP_AES_HMAC_SHA256 *key = data(ctx);
-
- switch (type)
- {
- case EVP_CTRL_AEAD_SET_MAC_KEY:
- {
- unsigned int i;
- unsigned char hmac_key[64];
-
- memset (hmac_key,0,sizeof(hmac_key));
-
- if (arg > (int)sizeof(hmac_key)) {
- SHA256_Init(&key->head);
- SHA256_Update(&key->head,ptr,arg);
- SHA256_Final(hmac_key,&key->head);
- } else {
- memcpy(hmac_key,ptr,arg);
- }
-
- for (i=0;i<sizeof(hmac_key);i++)
- hmac_key[i] ^= 0x36; /* ipad */
- SHA256_Init(&key->head);
- SHA256_Update(&key->head,hmac_key,sizeof(hmac_key));
-
- for (i=0;i<sizeof(hmac_key);i++)
- hmac_key[i] ^= 0x36^0x5c; /* opad */
- SHA256_Init(&key->tail);
- SHA256_Update(&key->tail,hmac_key,sizeof(hmac_key));
-
- OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
-
- return 1;
- }
- case EVP_CTRL_AEAD_TLS1_AAD:
- {
- unsigned char *p=ptr;
- unsigned int len=p[arg-2]<<8|p[arg-1];
-
- if (ctx->encrypt)
- {
- key->payload_length = len;
- if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
- len -= AES_BLOCK_SIZE;
- p[arg-2] = len>>8;
- p[arg-1] = len;
- }
- key->md = key->head;
- SHA256_Update(&key->md,p,arg);
-
- return (int)(((len+SHA256_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
- - len);
- }
- else
- {
- if (arg>13) arg = 13;
- memcpy(key->aux.tls_aad,ptr,arg);
- key->payload_length = arg;
-
- return SHA256_DIGEST_LENGTH;
- }
- }
-#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
- case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
- return (int)(5+16+((arg+32+16)&-16));
- case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
- {
- EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
- (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr;
- unsigned int n4x=1, x4;
- unsigned int frag, last, packlen, inp_len;
-
- if (arg<sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) return -1;
-
- inp_len = param->inp[11]<<8|param->inp[12];
-
- if (ctx->encrypt)
- {
- if ((param->inp[9]<<8|param->inp[10]) < TLS1_1_VERSION)
- return -1;
-
- if (inp_len)
- {
- if (inp_len<4096) return 0; /* too short */
-
- if (inp_len>=8192 && OPENSSL_ia32cap_P[2]&(1<<5))
- n4x=2; /* AVX2 */
- }
- else if ((n4x=param->interleave/4) && n4x<=2)
- inp_len = param->len;
- else
- return -1;
-
- key->md = key->head;
- SHA256_Update(&key->md,param->inp,13);
-
- x4 = 4*n4x; n4x += 1;
-
- frag = inp_len>>n4x;
- last = inp_len+frag-(frag<<n4x);
- if (last>frag && ((last+13+9)%64<(x4-1))) {
- frag++;
- last -= x4-1;
- }
-
- packlen = 5+16+((frag+32+16)&-16);
- packlen = (packlen<<n4x)-packlen;
- packlen += 5+16+((last+32+16)&-16);
-
- param->interleave = x4;
-
- return (int)packlen;
- }
- else
- return -1; /* not yet */
- }
- case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
- {
- EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
- (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr;
-
- return (int)tls1_1_multi_block_encrypt(key,param->out,param->inp,
- param->len,param->interleave/4);
- }
- case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
-#endif
- default:
- return -1;
- }
- }
-
-static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher =
- {
-#ifdef NID_aes_128_cbc_hmac_sha256
- NID_aes_128_cbc_hmac_sha256,
-#else
- NID_undef,
-#endif
- 16,16,16,
- EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|
- EVP_CIPH_FLAG_AEAD_CIPHER|EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
- aesni_cbc_hmac_sha256_init_key,
- aesni_cbc_hmac_sha256_cipher,
- NULL,
- sizeof(EVP_AES_HMAC_SHA256),
- EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
- EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
- aesni_cbc_hmac_sha256_ctrl,
- NULL
- };
-
-static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher =
- {
-#ifdef NID_aes_256_cbc_hmac_sha256
- NID_aes_256_cbc_hmac_sha256,
-#else
- NID_undef,
-#endif
- 16,32,16,
- EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|
- EVP_CIPH_FLAG_AEAD_CIPHER|EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
- aesni_cbc_hmac_sha256_init_key,
- aesni_cbc_hmac_sha256_cipher,
- NULL,
- sizeof(EVP_AES_HMAC_SHA256),
- EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
- EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
- aesni_cbc_hmac_sha256_ctrl,
- NULL
- };