155714Skris/* p12_mutl.c */ 2280297Sjkim/* 3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280297Sjkim * 1999. 555714Skris */ 655714Skris/* ==================================================================== 755714Skris * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 855714Skris * 955714Skris * Redistribution and use in source and binary forms, with or without 1055714Skris * modification, are permitted provided that the following conditions 1155714Skris * are met: 1255714Skris * 1355714Skris * 1. Redistributions of source code must retain the above copyright 14280297Sjkim * notice, this list of conditions and the following disclaimer. 1555714Skris * 1655714Skris * 2. Redistributions in binary form must reproduce the above copyright 1755714Skris * notice, this list of conditions and the following disclaimer in 1855714Skris * the documentation and/or other materials provided with the 1955714Skris * distribution. 2055714Skris * 2155714Skris * 3. All advertising materials mentioning features or use of this 2255714Skris * software must display the following acknowledgment: 2355714Skris * "This product includes software developed by the OpenSSL Project 2455714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2555714Skris * 2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2755714Skris * endorse or promote products derived from this software without 2855714Skris * prior written permission. For written permission, please contact 2955714Skris * licensing@OpenSSL.org. 3055714Skris * 3155714Skris * 5. Products derived from this software may not be called "OpenSSL" 3255714Skris * nor may "OpenSSL" appear in their names without prior written 3355714Skris * permission of the OpenSSL Project. 3455714Skris * 3555714Skris * 6. Redistributions of any form whatsoever must retain the following 3655714Skris * acknowledgment: 3755714Skris * "This product includes software developed by the OpenSSL Project 3855714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3955714Skris * 4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4355714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5255714Skris * ==================================================================== 5355714Skris * 5455714Skris * This product includes cryptographic software written by Eric Young 5555714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5655714Skris * Hudson (tjh@cryptsoft.com). 5755714Skris * 5855714Skris */ 5955714Skris 60109998Smarkm#ifndef OPENSSL_NO_HMAC 61280297Sjkim# include <stdio.h> 62280297Sjkim# include "cryptlib.h" 63284283Sjkim# include <openssl/crypto.h> 64280297Sjkim# include <openssl/hmac.h> 65280297Sjkim# include <openssl/rand.h> 66280297Sjkim# include <openssl/pkcs12.h> 6755714Skris 6855714Skris/* Generate a MAC */ 69160814Ssimonint PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, 70280297Sjkim unsigned char *mac, unsigned int *maclen) 7155714Skris{ 72280297Sjkim const EVP_MD *md_type; 73280297Sjkim HMAC_CTX hmac; 74280297Sjkim unsigned char key[EVP_MAX_MD_SIZE], *salt; 75280297Sjkim int saltlen, iter; 76280297Sjkim int md_size; 77109998Smarkm 78280297Sjkim if (!PKCS7_type_is_data(p12->authsafes)) { 79280297Sjkim PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); 80280297Sjkim return 0; 81280297Sjkim } 82160814Ssimon 83280297Sjkim salt = p12->mac->salt->data; 84280297Sjkim saltlen = p12->mac->salt->length; 85280297Sjkim if (!p12->mac->iter) 86280297Sjkim iter = 1; 87280297Sjkim else 88280297Sjkim iter = ASN1_INTEGER_get(p12->mac->iter); 89280297Sjkim if (!(md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm))) { 90280297Sjkim PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); 91280297Sjkim return 0; 92280297Sjkim } 93280297Sjkim md_size = EVP_MD_size(md_type); 94280297Sjkim if (md_size < 0) 95280297Sjkim return 0; 96280297Sjkim if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, 97280297Sjkim md_size, key, md_type)) { 98280297Sjkim PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); 99280297Sjkim return 0; 100280297Sjkim } 101280297Sjkim HMAC_CTX_init(&hmac); 102280297Sjkim if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) 103280297Sjkim || !HMAC_Update(&hmac, p12->authsafes->d.data->data, 104280297Sjkim p12->authsafes->d.data->length) 105280297Sjkim || !HMAC_Final(&hmac, mac, maclen)) { 106280297Sjkim HMAC_CTX_cleanup(&hmac); 107280297Sjkim return 0; 108280297Sjkim } 109280297Sjkim HMAC_CTX_cleanup(&hmac); 110280297Sjkim return 1; 11155714Skris} 11255714Skris 11355714Skris/* Verify the mac */ 114160814Ssimonint PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) 11555714Skris{ 116280297Sjkim unsigned char mac[EVP_MAX_MD_SIZE]; 117280297Sjkim unsigned int maclen; 118280297Sjkim if (p12->mac == NULL) { 119280297Sjkim PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT); 120280297Sjkim return 0; 121280297Sjkim } 122280297Sjkim if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { 123280297Sjkim PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR); 124280297Sjkim return 0; 125280297Sjkim } 126280297Sjkim if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) 127284283Sjkim || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen)) 128280297Sjkim return 0; 129280297Sjkim return 1; 13055714Skris} 13155714Skris 13255714Skris/* Set a mac */ 13355714Skris 134160814Ssimonint PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, 135280297Sjkim unsigned char *salt, int saltlen, int iter, 136280297Sjkim const EVP_MD *md_type) 13755714Skris{ 138280297Sjkim unsigned char mac[EVP_MAX_MD_SIZE]; 139280297Sjkim unsigned int maclen; 14055714Skris 141280297Sjkim if (!md_type) 142280297Sjkim md_type = EVP_sha1(); 143280297Sjkim if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { 144280297Sjkim PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR); 145280297Sjkim return 0; 146280297Sjkim } 147280297Sjkim if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { 148280297Sjkim PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR); 149280297Sjkim return 0; 150280297Sjkim } 151280297Sjkim if (!(M_ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))) { 152280297Sjkim PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR); 153280297Sjkim return 0; 154280297Sjkim } 155280297Sjkim return 1; 15655714Skris} 15755714Skris 15855714Skris/* Set up a mac structure */ 159160814Ssimonint PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, 160280297Sjkim const EVP_MD *md_type) 16155714Skris{ 162325335Sjkim PKCS12_MAC_DATA_free(p12->mac); 163325335Sjkim p12->mac = NULL; 164325335Sjkim 165325335Sjkim if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL) 166280297Sjkim return PKCS12_ERROR; 167280297Sjkim if (iter > 1) { 168280297Sjkim if (!(p12->mac->iter = M_ASN1_INTEGER_new())) { 169280297Sjkim PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 170280297Sjkim return 0; 171280297Sjkim } 172280297Sjkim if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { 173280297Sjkim PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 174280297Sjkim return 0; 175280297Sjkim } 176280297Sjkim } 177280297Sjkim if (!saltlen) 178280297Sjkim saltlen = PKCS12_SALT_LEN; 179291719Sjkim if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { 180280297Sjkim PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 181280297Sjkim return 0; 182280297Sjkim } 183291719Sjkim p12->mac->salt->length = saltlen; 184280297Sjkim if (!salt) { 185306195Sjkim if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0) 186280297Sjkim return 0; 187280297Sjkim } else 188280297Sjkim memcpy(p12->mac->salt->data, salt, saltlen); 189280297Sjkim p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); 190280297Sjkim if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { 191280297Sjkim PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); 192280297Sjkim return 0; 193280297Sjkim } 194280297Sjkim p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; 195280297Sjkim 196280297Sjkim return 1; 19755714Skris} 19855714Skris#endif 199