1/* 2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan 26 * (Royal Institute of Technology, Stockholm, Sweden). 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 33 * 1. Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * 36 * 2. Redistributions in binary form must reproduce the above copyright 37 * notice, this list of conditions and the following disclaimer in the 38 * documentation and/or other materials provided with the distribution. 39 * 40 * 3. Neither the name of the Institute nor the names of its contributors 41 * may be used to endorse or promote products derived from this software 42 * without specific prior written permission. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * SUCH DAMAGE. 55 */ 56 57#include <sys/types.h> 58#include <stdio.h> 59#include <stdlib.h> 60#include <string.h> 61 62#include "ossl-hmac.h" 63 64void 65HMAC_CTX_init(HMAC_CTX *ctx) 66{ 67 memset(ctx, 0, sizeof(*ctx)); 68} 69 70 71void 72HMAC_CTX_cleanup(HMAC_CTX *ctx) 73{ 74 EVP_MD_CTX_cleanup(&ctx->md_ctx); 75 EVP_MD_CTX_cleanup(&ctx->i_ctx); 76 EVP_MD_CTX_cleanup(&ctx->o_ctx); 77} 78 79 80size_t 81HMAC_size(const HMAC_CTX *ctx) 82{ 83 return (EVP_MD_size(ctx->md)); 84} 85 86 87void 88HMAC_Init_ex(HMAC_CTX *ctx, 89 const void *key, 90 size_t keylen, 91 const EVP_MD *md, 92 ENGINE *engine) 93{ 94 int i, blksize, reset = 0; 95 unsigned char pad[HMAC_MAX_MD_CBLOCK]; 96 97 if (md != NULL) { 98 reset = 1; 99 ctx->md = md; 100 } else{ 101 md = ctx->md; 102 } 103 104 if (key != NULL) { 105 reset = 1; 106 blksize = EVP_MD_block_size(md); 107 108 /* assert(j <= (int)sizeof(ctx->key)); */ 109 if (blksize < keylen) { 110 EVP_DigestInit_ex(&ctx->md_ctx, md, engine); 111 EVP_DigestUpdate(&ctx->md_ctx, key, keylen); 112 EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key, 113 &ctx->key_length); 114 } else { 115 /* assert(keylen>=0 && keylen<=(int)sizeof(ctx->buf)); */ 116 memcpy(ctx->key, key, keylen); 117 ctx->key_length = keylen; 118 } 119 if (ctx->key_length != HMAC_MAX_MD_CBLOCK) { 120 memset(&ctx->key[ctx->key_length], 0, 121 HMAC_MAX_MD_CBLOCK - ctx->key_length); 122 } 123 } 124 125 if (reset) { 126 for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) { 127 pad[i] = 0x36 ^ ctx->key[i]; 128 } 129 EVP_DigestInit_ex(&ctx->i_ctx, md, engine); 130 EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md)); 131 132 for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) { 133 pad[i] = 0x5c ^ ctx->key[i]; 134 } 135 EVP_DigestInit_ex(&ctx->o_ctx, md, engine); 136 EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md)); 137 } 138 139 EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx); 140} 141 142 143void 144HMAC_Init(HMAC_CTX *ctx, const void *key, size_t keylen, const EVP_MD *md) 145{ 146 if (key && md) { 147 HMAC_CTX_init(ctx); 148 } 149 HMAC_Init_ex(ctx, key, keylen, md, NULL); 150} 151 152 153void 154HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len) 155{ 156 EVP_DigestUpdate(&ctx->md_ctx, data, len); 157} 158 159 160void 161HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len) 162{ 163 unsigned int i; 164 unsigned char buf[EVP_MAX_MD_SIZE]; 165 166 EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i); 167 EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx); 168 EVP_DigestUpdate(&ctx->md_ctx, buf, i); 169 EVP_DigestFinal_ex(&ctx->md_ctx, md, len); 170} 171 172 173void * 174HMAC(const EVP_MD *md, 175 const void *key, size_t key_size, 176 const void *data, size_t data_size, 177 void *hash, unsigned int *hash_len) 178{ 179 HMAC_CTX ctx; 180 181 HMAC_CTX_init(&ctx); 182 HMAC_Init_ex(&ctx, key, key_size, md, NULL); 183 HMAC_Update(&ctx, data, data_size); 184 HMAC_Final(&ctx, hash, hash_len); 185 HMAC_CTX_cleanup(&ctx); 186 return (hash); 187} 188