1/* 2 * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10#include <stdio.h> 11#include <stdlib.h> 12#include "internal/cryptlib.h" 13#include <openssl/objects.h> 14#include <openssl/evp.h> 15#include "crypto/bn.h" 16#include "crypto/asn1.h" 17#include "crypto/evp.h" 18 19int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) 20{ 21 int ret; 22 if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { 23 EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, 24 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 25 return -2; 26 } 27 ctx->operation = EVP_PKEY_OP_PARAMGEN; 28 if (!ctx->pmeth->paramgen_init) 29 return 1; 30 ret = ctx->pmeth->paramgen_init(ctx); 31 if (ret <= 0) 32 ctx->operation = EVP_PKEY_OP_UNDEFINED; 33 return ret; 34} 35 36int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) 37{ 38 int ret; 39 if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { 40 EVPerr(EVP_F_EVP_PKEY_PARAMGEN, 41 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 42 return -2; 43 } 44 45 if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { 46 EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); 47 return -1; 48 } 49 50 if (ppkey == NULL) 51 return -1; 52 53 if (*ppkey == NULL) 54 *ppkey = EVP_PKEY_new(); 55 56 if (*ppkey == NULL) { 57 EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE); 58 return -1; 59 } 60 61 ret = ctx->pmeth->paramgen(ctx, *ppkey); 62 if (ret <= 0) { 63 EVP_PKEY_free(*ppkey); 64 *ppkey = NULL; 65 } 66 return ret; 67} 68 69int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) 70{ 71 int ret; 72 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { 73 EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, 74 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 75 return -2; 76 } 77 ctx->operation = EVP_PKEY_OP_KEYGEN; 78 if (!ctx->pmeth->keygen_init) 79 return 1; 80 ret = ctx->pmeth->keygen_init(ctx); 81 if (ret <= 0) 82 ctx->operation = EVP_PKEY_OP_UNDEFINED; 83 return ret; 84} 85 86int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) 87{ 88 int ret; 89 90 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { 91 EVPerr(EVP_F_EVP_PKEY_KEYGEN, 92 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 93 return -2; 94 } 95 if (ctx->operation != EVP_PKEY_OP_KEYGEN) { 96 EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); 97 return -1; 98 } 99 100 if (ppkey == NULL) 101 return -1; 102 103 if (*ppkey == NULL) 104 *ppkey = EVP_PKEY_new(); 105 if (*ppkey == NULL) 106 return -1; 107 108 ret = ctx->pmeth->keygen(ctx, *ppkey); 109 if (ret <= 0) { 110 EVP_PKEY_free(*ppkey); 111 *ppkey = NULL; 112 } 113 return ret; 114} 115 116void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) 117{ 118 ctx->pkey_gencb = cb; 119} 120 121EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) 122{ 123 return ctx->pkey_gencb; 124} 125 126/* 127 * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style 128 * callbacks. 129 */ 130 131static int trans_cb(int a, int b, BN_GENCB *gcb) 132{ 133 EVP_PKEY_CTX *ctx = BN_GENCB_get_arg(gcb); 134 ctx->keygen_info[0] = a; 135 ctx->keygen_info[1] = b; 136 return ctx->pkey_gencb(ctx); 137} 138 139void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) 140{ 141 BN_GENCB_set(cb, trans_cb, ctx); 142} 143 144int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) 145{ 146 if (idx == -1) 147 return ctx->keygen_info_count; 148 if (idx < 0 || idx > ctx->keygen_info_count) 149 return 0; 150 return ctx->keygen_info[idx]; 151} 152 153EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, 154 const unsigned char *key, int keylen) 155{ 156 EVP_PKEY_CTX *mac_ctx = NULL; 157 EVP_PKEY *mac_key = NULL; 158 mac_ctx = EVP_PKEY_CTX_new_id(type, e); 159 if (!mac_ctx) 160 return NULL; 161 if (EVP_PKEY_keygen_init(mac_ctx) <= 0) 162 goto merr; 163 if (EVP_PKEY_CTX_set_mac_key(mac_ctx, key, keylen) <= 0) 164 goto merr; 165 if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) 166 goto merr; 167 merr: 168 EVP_PKEY_CTX_free(mac_ctx); 169 return mac_key; 170} 171 172int EVP_PKEY_check(EVP_PKEY_CTX *ctx) 173{ 174 EVP_PKEY *pkey = ctx->pkey; 175 176 if (pkey == NULL) { 177 EVPerr(EVP_F_EVP_PKEY_CHECK, EVP_R_NO_KEY_SET); 178 return 0; 179 } 180 181 /* call customized check function first */ 182 if (ctx->pmeth->check != NULL) 183 return ctx->pmeth->check(pkey); 184 185 /* use default check function in ameth */ 186 if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) { 187 EVPerr(EVP_F_EVP_PKEY_CHECK, 188 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 189 return -2; 190 } 191 192 return pkey->ameth->pkey_check(pkey); 193} 194 195int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx) 196{ 197 EVP_PKEY *pkey = ctx->pkey; 198 199 if (pkey == NULL) { 200 EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, EVP_R_NO_KEY_SET); 201 return 0; 202 } 203 204 /* call customized public key check function first */ 205 if (ctx->pmeth->public_check != NULL) 206 return ctx->pmeth->public_check(pkey); 207 208 /* use default public key check function in ameth */ 209 if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) { 210 EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, 211 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 212 return -2; 213 } 214 215 return pkey->ameth->pkey_public_check(pkey); 216} 217 218int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx) 219{ 220 EVP_PKEY *pkey = ctx->pkey; 221 222 if (pkey == NULL) { 223 EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, EVP_R_NO_KEY_SET); 224 return 0; 225 } 226 227 /* call customized param check function first */ 228 if (ctx->pmeth->param_check != NULL) 229 return ctx->pmeth->param_check(pkey); 230 231 /* use default param check function in ameth */ 232 if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) { 233 EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, 234 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 235 return -2; 236 } 237 238 return pkey->ameth->pkey_param_check(pkey); 239} 240