1 /* $OpenBSD: pmeth_fn.c,v 1.6 2017/01/29 17:49:23 beck Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2006. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <stdio.h> 60 #include <stdlib.h> 61 62 #include <openssl/err.h> 63 #include <openssl/evp.h> 64 #include <openssl/objects.h> 65 66 #include "evp_locl.h" 67 68 #define M_check_autoarg(ctx, arg, arglen, err) \ 69 if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \ 70 { \ 71 size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ 72 if (!arg) \ 73 { \ 74 *arglen = pksize; \ 75 return 1; \ 76 } \ 77 else if (*arglen < pksize) \ 78 { \ 79 EVPerror(EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\ 80 return 0; \ 81 } \ 82 } 83 84 int 85 EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) 86 { 87 int ret; 88 89 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 90 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 91 return -2; 92 } 93 ctx->operation = EVP_PKEY_OP_SIGN; 94 if (!ctx->pmeth->sign_init) 95 return 1; 96 ret = ctx->pmeth->sign_init(ctx); 97 if (ret <= 0) 98 ctx->operation = EVP_PKEY_OP_UNDEFINED; 99 return ret; 100 } 101 102 int 103 EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 104 const unsigned char *tbs, size_t tbslen) 105 { 106 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 107 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 108 return -2; 109 } 110 if (ctx->operation != EVP_PKEY_OP_SIGN) { 111 EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); 112 return -1; 113 } 114 M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) 115 return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); 116 } 117 118 int 119 EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) 120 { 121 int ret; 122 123 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 124 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 125 return -2; 126 } 127 ctx->operation = EVP_PKEY_OP_VERIFY; 128 if (!ctx->pmeth->verify_init) 129 return 1; 130 ret = ctx->pmeth->verify_init(ctx); 131 if (ret <= 0) 132 ctx->operation = EVP_PKEY_OP_UNDEFINED; 133 return ret; 134 } 135 136 int 137 EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, 138 const unsigned char *tbs, size_t tbslen) 139 { 140 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 141 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 142 return -2; 143 } 144 if (ctx->operation != EVP_PKEY_OP_VERIFY) { 145 EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); 146 return -1; 147 } 148 return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); 149 } 150 151 int 152 EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) 153 { 154 int ret; 155 156 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { 157 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 158 return -2; 159 } 160 ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; 161 if (!ctx->pmeth->verify_recover_init) 162 return 1; 163 ret = ctx->pmeth->verify_recover_init(ctx); 164 if (ret <= 0) 165 ctx->operation = EVP_PKEY_OP_UNDEFINED; 166 return ret; 167 } 168 169 int 170 EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, 171 const unsigned char *sig, size_t siglen) 172 { 173 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { 174 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 175 return -2; 176 } 177 if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { 178 EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); 179 return -1; 180 } 181 M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) 182 return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); 183 } 184 185 int 186 EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) 187 { 188 int ret; 189 190 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 191 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 192 return -2; 193 } 194 ctx->operation = EVP_PKEY_OP_ENCRYPT; 195 if (!ctx->pmeth->encrypt_init) 196 return 1; 197 ret = ctx->pmeth->encrypt_init(ctx); 198 if (ret <= 0) 199 ctx->operation = EVP_PKEY_OP_UNDEFINED; 200 return ret; 201 } 202 203 int 204 EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, 205 const unsigned char *in, size_t inlen) 206 { 207 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 208 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 209 return -2; 210 } 211 if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { 212 EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); 213 return -1; 214 } 215 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) 216 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); 217 } 218 219 int 220 EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) 221 { 222 int ret; 223 224 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 225 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 226 return -2; 227 } 228 ctx->operation = EVP_PKEY_OP_DECRYPT; 229 if (!ctx->pmeth->decrypt_init) 230 return 1; 231 ret = ctx->pmeth->decrypt_init(ctx); 232 if (ret <= 0) 233 ctx->operation = EVP_PKEY_OP_UNDEFINED; 234 return ret; 235 } 236 237 int 238 EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, 239 const unsigned char *in, size_t inlen) 240 { 241 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 242 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 243 return -2; 244 } 245 if (ctx->operation != EVP_PKEY_OP_DECRYPT) { 246 EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); 247 return -1; 248 } 249 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) 250 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); 251 } 252 253 int 254 EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) 255 { 256 int ret; 257 258 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 259 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 260 return -2; 261 } 262 ctx->operation = EVP_PKEY_OP_DERIVE; 263 if (!ctx->pmeth->derive_init) 264 return 1; 265 ret = ctx->pmeth->derive_init(ctx); 266 if (ret <= 0) 267 ctx->operation = EVP_PKEY_OP_UNDEFINED; 268 return ret; 269 } 270 271 int 272 EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) 273 { 274 int ret; 275 276 if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive || 277 ctx->pmeth->encrypt || ctx->pmeth->decrypt) || 278 !ctx->pmeth->ctrl) { 279 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 280 return -2; 281 } 282 if (ctx->operation != EVP_PKEY_OP_DERIVE && 283 ctx->operation != EVP_PKEY_OP_ENCRYPT && 284 ctx->operation != EVP_PKEY_OP_DECRYPT) { 285 EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); 286 return -1; 287 } 288 289 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); 290 291 if (ret <= 0) 292 return ret; 293 294 if (ret == 2) 295 return 1; 296 297 if (!ctx->pkey) { 298 EVPerror(EVP_R_NO_KEY_SET); 299 return -1; 300 } 301 302 if (ctx->pkey->type != peer->type) { 303 EVPerror(EVP_R_DIFFERENT_KEY_TYPES); 304 return -1; 305 } 306 307 /* ran@cryptocom.ru: For clarity. The error is if parameters in peer are 308 * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return 309 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 310 * (different key types) is impossible here because it is checked earlier. 311 * -2 is OK for us here, as well as 1, so we can check for 0 only. */ 312 if (!EVP_PKEY_missing_parameters(peer) && 313 !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { 314 EVPerror(EVP_R_DIFFERENT_PARAMETERS); 315 return -1; 316 } 317 318 EVP_PKEY_free(ctx->peerkey); 319 ctx->peerkey = peer; 320 321 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); 322 323 if (ret <= 0) { 324 ctx->peerkey = NULL; 325 return ret; 326 } 327 328 CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY); 329 return 1; 330 } 331 332 int 333 EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) 334 { 335 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 336 EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 337 return -2; 338 } 339 if (ctx->operation != EVP_PKEY_OP_DERIVE) { 340 EVPerror(EVP_R_OPERATON_NOT_INITIALIZED); 341 return -1; 342 } 343 M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) 344 return ctx->pmeth->derive(ctx, key, pkeylen); 345 } 346