| OLD | NEW |
| (Empty) |
| 1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | |
| 2 * project 2010. | |
| 3 */ | |
| 4 /* ==================================================================== | |
| 5 * Copyright (c) 2010 The OpenSSL Project. All rights reserved. | |
| 6 * | |
| 7 * Redistribution and use in source and binary forms, with or without | |
| 8 * modification, are permitted provided that the following conditions | |
| 9 * are met: | |
| 10 * | |
| 11 * 1. Redistributions of source code must retain the above copyright | |
| 12 * notice, this list of conditions and the following disclaimer. | |
| 13 * | |
| 14 * 2. Redistributions in binary form must reproduce the above copyright | |
| 15 * notice, this list of conditions and the following disclaimer in | |
| 16 * the documentation and/or other materials provided with the | |
| 17 * distribution. | |
| 18 * | |
| 19 * 3. All advertising materials mentioning features or use of this | |
| 20 * software must display the following acknowledgment: | |
| 21 * "This product includes software developed by the OpenSSL Project | |
| 22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
| 23 * | |
| 24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
| 25 * endorse or promote products derived from this software without | |
| 26 * prior written permission. For written permission, please contact | |
| 27 * licensing@OpenSSL.org. | |
| 28 * | |
| 29 * 5. Products derived from this software may not be called "OpenSSL" | |
| 30 * nor may "OpenSSL" appear in their names without prior written | |
| 31 * permission of the OpenSSL Project. | |
| 32 * | |
| 33 * 6. Redistributions of any form whatsoever must retain the following | |
| 34 * acknowledgment: | |
| 35 * "This product includes software developed by the OpenSSL Project | |
| 36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
| 37 * | |
| 38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
| 39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
| 42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
| 49 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 50 * ==================================================================== | |
| 51 */ | |
| 52 | |
| 53 #include <stdio.h> | |
| 54 #include "cryptlib.h" | |
| 55 #include <openssl/x509.h> | |
| 56 #include <openssl/x509v3.h> | |
| 57 #include <openssl/evp.h> | |
| 58 #include <openssl/cmac.h> | |
| 59 #include "evp_locl.h" | |
| 60 | |
| 61 /* The context structure and "key" is simply a CMAC_CTX */ | |
| 62 | |
| 63 static int pkey_cmac_init(EVP_PKEY_CTX *ctx) | |
| 64 { | |
| 65 ctx->data = CMAC_CTX_new(); | |
| 66 if (!ctx->data) | |
| 67 return 0; | |
| 68 ctx->keygen_info_count = 0; | |
| 69 return 1; | |
| 70 } | |
| 71 | |
| 72 static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | |
| 73 { | |
| 74 if (!pkey_cmac_init(dst)) | |
| 75 return 0; | |
| 76 if (!CMAC_CTX_copy(dst->data, src->data)) | |
| 77 return 0; | |
| 78 return 1; | |
| 79 } | |
| 80 | |
| 81 static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) | |
| 82 { | |
| 83 CMAC_CTX_free(ctx->data); | |
| 84 } | |
| 85 | |
| 86 static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | |
| 87 { | |
| 88 CMAC_CTX *cmkey = CMAC_CTX_new(); | |
| 89 CMAC_CTX *cmctx = ctx->data; | |
| 90 if (!cmkey) | |
| 91 return 0; | |
| 92 if (!CMAC_CTX_copy(cmkey, cmctx)) | |
| 93 { | |
| 94 CMAC_CTX_free(cmkey); | |
| 95 return 0; | |
| 96 } | |
| 97 EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); | |
| 98 | |
| 99 return 1; | |
| 100 } | |
| 101 | |
| 102 static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count) | |
| 103 { | |
| 104 if (!CMAC_Update(ctx->pctx->data, data, count)) | |
| 105 return 0; | |
| 106 return 1; | |
| 107 } | |
| 108 | |
| 109 static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) | |
| 110 { | |
| 111 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); | |
| 112 mctx->update = int_update; | |
| 113 return 1; | |
| 114 } | |
| 115 | |
| 116 static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, | |
| 117 EVP_MD_CTX *mctx) | |
| 118 { | |
| 119 return CMAC_Final(ctx->data, sig, siglen); | |
| 120 } | |
| 121 | |
| 122 static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | |
| 123 { | |
| 124 CMAC_CTX *cmctx = ctx->data; | |
| 125 switch (type) | |
| 126 { | |
| 127 | |
| 128 case EVP_PKEY_CTRL_SET_MAC_KEY: | |
| 129 if (!p2 || p1 < 0) | |
| 130 return 0; | |
| 131 if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) | |
| 132 return 0; | |
| 133 break; | |
| 134 | |
| 135 case EVP_PKEY_CTRL_CIPHER: | |
| 136 if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) | |
| 137 return 0; | |
| 138 break; | |
| 139 | |
| 140 case EVP_PKEY_CTRL_MD: | |
| 141 if (ctx->pkey && !CMAC_CTX_copy(ctx->data, | |
| 142 (CMAC_CTX *)ctx->pkey->pkey.ptr)) | |
| 143 return 0; | |
| 144 if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) | |
| 145 return 0; | |
| 146 break; | |
| 147 | |
| 148 default: | |
| 149 return -2; | |
| 150 | |
| 151 } | |
| 152 return 1; | |
| 153 } | |
| 154 | |
| 155 static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, | |
| 156 const char *type, const char *value) | |
| 157 { | |
| 158 if (!value) | |
| 159 { | |
| 160 return 0; | |
| 161 } | |
| 162 if (!strcmp(type, "key")) | |
| 163 { | |
| 164 void *p = (void *)value; | |
| 165 return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, | |
| 166 strlen(p), p); | |
| 167 } | |
| 168 if (!strcmp(type, "cipher")) | |
| 169 { | |
| 170 const EVP_CIPHER *c; | |
| 171 c = EVP_get_cipherbyname(value); | |
| 172 if (!c) | |
| 173 return 0; | |
| 174 return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); | |
| 175 } | |
| 176 if (!strcmp(type, "hexkey")) | |
| 177 { | |
| 178 unsigned char *key; | |
| 179 int r; | |
| 180 long keylen; | |
| 181 key = string_to_hex(value, &keylen); | |
| 182 if (!key) | |
| 183 return 0; | |
| 184 r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); | |
| 185 OPENSSL_free(key); | |
| 186 return r; | |
| 187 } | |
| 188 return -2; | |
| 189 } | |
| 190 | |
| 191 const EVP_PKEY_METHOD cmac_pkey_meth = | |
| 192 { | |
| 193 EVP_PKEY_CMAC, | |
| 194 EVP_PKEY_FLAG_SIGCTX_CUSTOM, | |
| 195 pkey_cmac_init, | |
| 196 pkey_cmac_copy, | |
| 197 pkey_cmac_cleanup, | |
| 198 | |
| 199 0, 0, | |
| 200 | |
| 201 0, | |
| 202 pkey_cmac_keygen, | |
| 203 | |
| 204 0, 0, | |
| 205 | |
| 206 0, 0, | |
| 207 | |
| 208 0,0, | |
| 209 | |
| 210 cmac_signctx_init, | |
| 211 cmac_signctx, | |
| 212 | |
| 213 0,0, | |
| 214 | |
| 215 0,0, | |
| 216 | |
| 217 0,0, | |
| 218 | |
| 219 0,0, | |
| 220 | |
| 221 pkey_cmac_ctrl, | |
| 222 pkey_cmac_ctrl_str | |
| 223 | |
| 224 }; | |
| OLD | NEW |