1280304Sjkim/* 2280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 3280304Sjkim * 2010. 4238384Sjkim */ 5238384Sjkim/* ==================================================================== 6238384Sjkim * Copyright (c) 2010 The OpenSSL Project. All rights reserved. 7238384Sjkim * 8238384Sjkim * Redistribution and use in source and binary forms, with or without 9238384Sjkim * modification, are permitted provided that the following conditions 10238384Sjkim * are met: 11238384Sjkim * 12238384Sjkim * 1. Redistributions of source code must retain the above copyright 13280304Sjkim * notice, this list of conditions and the following disclaimer. 14238384Sjkim * 15238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 16238384Sjkim * notice, this list of conditions and the following disclaimer in 17238384Sjkim * the documentation and/or other materials provided with the 18238384Sjkim * distribution. 19238384Sjkim * 20238384Sjkim * 3. All advertising materials mentioning features or use of this 21238384Sjkim * software must display the following acknowledgment: 22238384Sjkim * "This product includes software developed by the OpenSSL Project 23238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24238384Sjkim * 25238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26238384Sjkim * endorse or promote products derived from this software without 27238384Sjkim * prior written permission. For written permission, please contact 28238384Sjkim * licensing@OpenSSL.org. 29238384Sjkim * 30238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 31238384Sjkim * nor may "OpenSSL" appear in their names without prior written 32238384Sjkim * permission of the OpenSSL Project. 33238384Sjkim * 34238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 35238384Sjkim * acknowledgment: 36238384Sjkim * "This product includes software developed by the OpenSSL Project 37238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38238384Sjkim * 39238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 51238384Sjkim * ==================================================================== 52238384Sjkim */ 53238384Sjkim 54238384Sjkim#include <stdio.h> 55238384Sjkim#include "cryptlib.h" 56238384Sjkim#include <openssl/x509.h> 57238384Sjkim#include <openssl/x509v3.h> 58238384Sjkim#include <openssl/evp.h> 59238384Sjkim#include <openssl/cmac.h> 60238384Sjkim#include "evp_locl.h" 61238384Sjkim 62238384Sjkim/* The context structure and "key" is simply a CMAC_CTX */ 63238384Sjkim 64238384Sjkimstatic int pkey_cmac_init(EVP_PKEY_CTX *ctx) 65280304Sjkim{ 66280304Sjkim ctx->data = CMAC_CTX_new(); 67280304Sjkim if (!ctx->data) 68280304Sjkim return 0; 69280304Sjkim ctx->keygen_info_count = 0; 70280304Sjkim return 1; 71280304Sjkim} 72238384Sjkim 73238384Sjkimstatic int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 74280304Sjkim{ 75280304Sjkim if (!pkey_cmac_init(dst)) 76280304Sjkim return 0; 77280304Sjkim if (!CMAC_CTX_copy(dst->data, src->data)) 78280304Sjkim return 0; 79280304Sjkim return 1; 80280304Sjkim} 81238384Sjkim 82238384Sjkimstatic void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) 83280304Sjkim{ 84280304Sjkim CMAC_CTX_free(ctx->data); 85280304Sjkim} 86238384Sjkim 87238384Sjkimstatic int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 88280304Sjkim{ 89280304Sjkim CMAC_CTX *cmkey = CMAC_CTX_new(); 90280304Sjkim CMAC_CTX *cmctx = ctx->data; 91280304Sjkim if (!cmkey) 92280304Sjkim return 0; 93280304Sjkim if (!CMAC_CTX_copy(cmkey, cmctx)) { 94280304Sjkim CMAC_CTX_free(cmkey); 95280304Sjkim return 0; 96280304Sjkim } 97280304Sjkim EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); 98238384Sjkim 99280304Sjkim return 1; 100280304Sjkim} 101238384Sjkim 102280304Sjkimstatic int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) 103280304Sjkim{ 104280304Sjkim if (!CMAC_Update(ctx->pctx->data, data, count)) 105280304Sjkim return 0; 106280304Sjkim return 1; 107280304Sjkim} 108280304Sjkim 109238384Sjkimstatic int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) 110280304Sjkim{ 111280304Sjkim EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); 112280304Sjkim mctx->update = int_update; 113280304Sjkim return 1; 114280304Sjkim} 115238384Sjkim 116238384Sjkimstatic int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 117280304Sjkim EVP_MD_CTX *mctx) 118280304Sjkim{ 119280304Sjkim return CMAC_Final(ctx->data, sig, siglen); 120280304Sjkim} 121238384Sjkim 122238384Sjkimstatic int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 123280304Sjkim{ 124280304Sjkim CMAC_CTX *cmctx = ctx->data; 125280304Sjkim switch (type) { 126238384Sjkim 127280304Sjkim case EVP_PKEY_CTRL_SET_MAC_KEY: 128280304Sjkim if (!p2 || p1 < 0) 129280304Sjkim return 0; 130280304Sjkim if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) 131280304Sjkim return 0; 132280304Sjkim break; 133238384Sjkim 134280304Sjkim case EVP_PKEY_CTRL_CIPHER: 135280304Sjkim if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) 136280304Sjkim return 0; 137280304Sjkim break; 138238384Sjkim 139280304Sjkim case EVP_PKEY_CTRL_MD: 140280304Sjkim if (ctx->pkey && !CMAC_CTX_copy(ctx->data, 141280304Sjkim (CMAC_CTX *)ctx->pkey->pkey.ptr)) 142280304Sjkim return 0; 143280304Sjkim if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) 144280304Sjkim return 0; 145280304Sjkim break; 146238384Sjkim 147280304Sjkim default: 148280304Sjkim return -2; 149238384Sjkim 150280304Sjkim } 151280304Sjkim return 1; 152280304Sjkim} 153238384Sjkim 154238384Sjkimstatic int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, 155280304Sjkim const char *type, const char *value) 156280304Sjkim{ 157280304Sjkim if (!value) { 158280304Sjkim return 0; 159280304Sjkim } 160280304Sjkim if (!strcmp(type, "key")) { 161280304Sjkim void *p = (void *)value; 162280304Sjkim return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, strlen(p), p); 163280304Sjkim } 164280304Sjkim if (!strcmp(type, "cipher")) { 165280304Sjkim const EVP_CIPHER *c; 166280304Sjkim c = EVP_get_cipherbyname(value); 167280304Sjkim if (!c) 168280304Sjkim return 0; 169280304Sjkim return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); 170280304Sjkim } 171280304Sjkim if (!strcmp(type, "hexkey")) { 172280304Sjkim unsigned char *key; 173280304Sjkim int r; 174280304Sjkim long keylen; 175280304Sjkim key = string_to_hex(value, &keylen); 176280304Sjkim if (!key) 177280304Sjkim return 0; 178280304Sjkim r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); 179280304Sjkim OPENSSL_free(key); 180280304Sjkim return r; 181280304Sjkim } 182280304Sjkim return -2; 183280304Sjkim} 184238384Sjkim 185280304Sjkimconst EVP_PKEY_METHOD cmac_pkey_meth = { 186280304Sjkim EVP_PKEY_CMAC, 187280304Sjkim EVP_PKEY_FLAG_SIGCTX_CUSTOM, 188280304Sjkim pkey_cmac_init, 189280304Sjkim pkey_cmac_copy, 190280304Sjkim pkey_cmac_cleanup, 191238384Sjkim 192280304Sjkim 0, 0, 193238384Sjkim 194280304Sjkim 0, 195280304Sjkim pkey_cmac_keygen, 196238384Sjkim 197280304Sjkim 0, 0, 198238384Sjkim 199280304Sjkim 0, 0, 200238384Sjkim 201280304Sjkim 0, 0, 202238384Sjkim 203280304Sjkim cmac_signctx_init, 204280304Sjkim cmac_signctx, 205238384Sjkim 206280304Sjkim 0, 0, 207238384Sjkim 208280304Sjkim 0, 0, 209238384Sjkim 210280304Sjkim 0, 0, 211238384Sjkim 212280304Sjkim 0, 0, 213238384Sjkim 214280304Sjkim pkey_cmac_ctrl, 215280304Sjkim pkey_cmac_ctrl_str 216280304Sjkim}; 217