1392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* ==================================================================== 2392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Copyright (c) 2011 The OpenSSL Project. All rights reserved. 3392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 4392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Redistribution and use in source and binary forms, with or without 5392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * modification, are permitted provided that the following conditions 6392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * are met: 7392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 8392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 1. Redistributions of source code must retain the above copyright 9392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * notice, this list of conditions and the following disclaimer. 10392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 11392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 2. Redistributions in binary form must reproduce the above copyright 12392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * notice, this list of conditions and the following disclaimer in 13392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * the documentation and/or other materials provided with the 14392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * distribution. 15392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 16392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 3. All advertising materials mentioning features or use of this 17392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * software must display the following acknowledgment: 18392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 19392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 20392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 21392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * endorse or promote products derived from this software without 23392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * prior written permission. For written permission, please contact 24392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * licensing@OpenSSL.org. 25392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 26392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 5. Products derived from this software may not be called "OpenSSL" 27392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * nor may "OpenSSL" appear in their names without prior written 28392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * permission of the OpenSSL Project. 29392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 30392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 6. Redistributions of any form whatsoever must retain the following 31392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * acknowledgment: 32392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 33392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 34392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 35392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * OF THE POSSIBILITY OF SUCH DAMAGE. 47392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ==================================================================== 48392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 49392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 50392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/opensslconf.h> 51392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 52392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <stdio.h> 53392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <string.h> 54392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 55392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5) 56392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 57392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/evp.h> 58392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/objects.h> 59392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/rc4.h> 60392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/md5.h> 61392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 62392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef EVP_CIPH_FLAG_AEAD_CIPHER 63392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 64392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define EVP_CTRL_AEAD_TLS1_AAD 0x16 65392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 66392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 67392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* FIXME: surely this is available elsewhere? */ 69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define EVP_RC4_KEY_SIZE 16 70392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 71392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef struct 72392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 73392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom RC4_KEY ks; 74392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_CTX head,tail,md; 75392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t payload_length; 76392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } EVP_RC4_HMAC_MD5; 77392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 78a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom#define NO_PAYLOAD_LENGTH ((size_t)-1) 79a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom 80392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid rc4_md5_enc (RC4_KEY *key, const void *in0, void *out, 81392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_CTX *ctx,const void *inp,size_t blocks); 82392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 83392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data) 84392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 85392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, 86392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *inkey, 87392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *iv, int enc) 88392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 89392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_RC4_HMAC_MD5 *key = data(ctx); 90392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 91392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom RC4_set_key(&key->ks,EVP_CIPHER_CTX_key_length(ctx), 92392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom inkey); 93392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 94392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Init(&key->head); /* handy when benchmarking */ 95392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->tail = key->head; 96392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md = key->head; 97392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 98a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom key->payload_length = NO_PAYLOAD_LENGTH; 99392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 100392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 101392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 103392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if !defined(OPENSSL_NO_ASM) && ( \ 104392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom defined(__x86_64) || defined(__x86_64__) || \ 105392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom defined(_M_AMD64) || defined(_M_X64) || \ 106f42d491ab90c82302b0054c62014c1ee9b638affBrian Carlstrom defined(__INTEL__) ) && \ 107f42d491ab90c82302b0054c62014c1ee9b638affBrian Carlstrom !(defined(__APPLE__) && defined(__MACH__)) 108392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define STITCHED_CALL 109392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if !defined(STITCHED_CALL) 112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define rc4_off 0 113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define md5_off 0 114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *in, size_t len) 118392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 119392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_RC4_HMAC_MD5 *key = data(ctx); 120392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(STITCHED_CALL) 121392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t rc4_off = 32-1-(key->ks.x&(32-1)), /* 32 is $MOD from rc4_md5-x86_64.pl */ 122392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom md5_off = MD5_CBLOCK-key->md.num, 123392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom blocks; 124392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int l; 125f42d491ab90c82302b0054c62014c1ee9b638affBrian Carlstrom extern unsigned int OPENSSL_ia32cap_P[]; 126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t plen = key->payload_length; 128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 129a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom if (plen!=NO_PAYLOAD_LENGTH && len!=(plen+MD5_DIGEST_LENGTH)) return 0; 130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->encrypt) { 132a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom if (plen==NO_PAYLOAD_LENGTH) plen = len; 133392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(STITCHED_CALL) 134392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* cipher has to "fall behind" */ 135392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (rc4_off>md5_off) md5_off+=MD5_CBLOCK; 136392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 137f42d491ab90c82302b0054c62014c1ee9b638affBrian Carlstrom if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK) && 138f42d491ab90c82302b0054c62014c1ee9b638affBrian Carlstrom (OPENSSL_ia32cap_P[0]&(1<<20))==0) { 139392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,in,md5_off); 140392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom RC4(&key->ks,rc4_off,in,out); 141392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 142392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off, 143392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom &key->md,in+md5_off,blocks); 144392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom blocks *= MD5_CBLOCK; 145392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_off += blocks; 146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom md5_off += blocks; 147392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md.Nh += blocks>>29; 148392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md.Nl += blocks<<=3; 149392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (key->md.Nl<(unsigned int)blocks) key->md.Nh++; 150392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } else { 151392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_off = 0; 152392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom md5_off = 0; 153392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 154392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 155392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,in+md5_off,plen-md5_off); 156392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 157392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (plen!=len) { /* "TLS" mode of operation */ 158392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (in!=out) 159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(out+rc4_off,in+rc4_off,plen-rc4_off); 160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* calculate HMAC and append it to payload */ 162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Final(out+plen,&key->md); 163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md = key->tail; 164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,out+plen,MD5_DIGEST_LENGTH); 165392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Final(out+plen,&key->md); 166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* encrypt HMAC at once */ 167392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom RC4(&key->ks,len-rc4_off,out+rc4_off,out+rc4_off); 168392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } else { 169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off); 170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } else { 172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char mac[MD5_DIGEST_LENGTH]; 173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(STITCHED_CALL) 174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* digest has to "fall behind" */ 175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (md5_off>rc4_off) rc4_off += 2*MD5_CBLOCK; 176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom else rc4_off += MD5_CBLOCK; 177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 178f42d491ab90c82302b0054c62014c1ee9b638affBrian Carlstrom if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK) && 179f42d491ab90c82302b0054c62014c1ee9b638affBrian Carlstrom (OPENSSL_ia32cap_P[0]&(1<<20))==0) { 180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom RC4(&key->ks,rc4_off,in,out); 181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,out,md5_off); 182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off, 184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom &key->md,out+md5_off,blocks); 185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom blocks *= MD5_CBLOCK; 186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_off += blocks; 187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom md5_off += blocks; 188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom l = (key->md.Nl+(blocks<<3))&0xffffffffU; 189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (l<key->md.Nl) key->md.Nh++; 190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md.Nl = l; 191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md.Nh += blocks>>29; 192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } else { 193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom md5_off=0; 194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_off=0; 195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* decrypt HMAC at once */ 198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off); 199a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom if (plen!=NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ 200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,out+md5_off,plen-md5_off); 201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* calculate HMAC and verify it */ 203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Final(mac,&key->md); 204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md = key->tail; 205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH); 206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Final(mac,&key->md); 207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH)) 209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } else { 211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,out+md5_off,len-md5_off); 212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 215a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom key->payload_length = NO_PAYLOAD_LENGTH; 216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) 221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_RC4_HMAC_MD5 *key = data(ctx); 223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom switch (type) 225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom case EVP_CTRL_AEAD_SET_MAC_KEY: 227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int i; 229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char hmac_key[64]; 230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memset (hmac_key,0,sizeof(hmac_key)); 232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (arg > (int)sizeof(hmac_key)) { 234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Init(&key->head); 235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->head,ptr,arg); 236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Final(hmac_key,&key->head); 237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } else { 238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(hmac_key,ptr,arg); 239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0;i<sizeof(hmac_key);i++) 242392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom hmac_key[i] ^= 0x36; /* ipad */ 243392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Init(&key->head); 244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->head,hmac_key,sizeof(hmac_key)); 245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0;i<sizeof(hmac_key);i++) 247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom hmac_key[i] ^= 0x36^0x5c; /* opad */ 248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Init(&key->tail); 249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->tail,hmac_key,sizeof(hmac_key)); 250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 251392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 1; 252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 253392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom case EVP_CTRL_AEAD_TLS1_AAD: 254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char *p=ptr; 256392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int len=p[arg-2]<<8|p[arg-1]; 257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!ctx->encrypt) 259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom len -= MD5_DIGEST_LENGTH; 261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom p[arg-2] = len>>8; 262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom p[arg-1] = len; 263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->payload_length=len; 265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->md = key->head; 266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom MD5_Update(&key->md,p,arg); 267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return MD5_DIGEST_LENGTH; 269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom default: 271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return -1; 272392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 273392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 274392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 275392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic EVP_CIPHER r4_hmac_md5_cipher= 276392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 277392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef NID_rc4_hmac_md5 278392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom NID_rc4_hmac_md5, 279392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom NID_undef, 281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 1,EVP_RC4_KEY_SIZE,0, 283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH|EVP_CIPH_FLAG_AEAD_CIPHER, 284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_hmac_md5_init_key, 285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_hmac_md5_cipher, 286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom NULL, 287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom sizeof(EVP_RC4_HMAC_MD5), 288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom NULL, 289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom NULL, 290392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom rc4_hmac_md5_ctrl, 291392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom NULL 292392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom }; 293392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 294392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromconst EVP_CIPHER *EVP_rc4_hmac_md5(void) 295392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 296392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return(&r4_hmac_md5_cipher); 297392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 299