[331] | 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 "internal/evp_int.h"
|
---|
| 16 |
|
---|
| 17 | #define M_check_autoarg(ctx, arg, arglen, err) \
|
---|
| 18 | if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \
|
---|
| 19 | size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
|
---|
| 20 | \
|
---|
| 21 | if (pksize == 0) { \
|
---|
| 22 | EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \
|
---|
| 23 | return 0; \
|
---|
| 24 | } \
|
---|
| 25 | if (!arg) { \
|
---|
| 26 | *arglen = pksize; \
|
---|
| 27 | return 1; \
|
---|
| 28 | } \
|
---|
| 29 | if (*arglen < pksize) { \
|
---|
| 30 | EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
|
---|
| 31 | return 0; \
|
---|
| 32 | } \
|
---|
| 33 | }
|
---|
| 34 |
|
---|
| 35 | int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
|
---|
| 36 | {
|
---|
| 37 | int ret;
|
---|
| 38 | if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
|
---|
| 39 | EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
|
---|
| 40 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 41 | return -2;
|
---|
| 42 | }
|
---|
| 43 | ctx->operation = EVP_PKEY_OP_SIGN;
|
---|
| 44 | if (!ctx->pmeth->sign_init)
|
---|
| 45 | return 1;
|
---|
| 46 | ret = ctx->pmeth->sign_init(ctx);
|
---|
| 47 | if (ret <= 0)
|
---|
| 48 | ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
---|
| 49 | return ret;
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
|
---|
| 53 | unsigned char *sig, size_t *siglen,
|
---|
| 54 | const unsigned char *tbs, size_t tbslen)
|
---|
| 55 | {
|
---|
| 56 | if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
|
---|
| 57 | EVPerr(EVP_F_EVP_PKEY_SIGN,
|
---|
| 58 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 59 | return -2;
|
---|
| 60 | }
|
---|
| 61 | if (ctx->operation != EVP_PKEY_OP_SIGN) {
|
---|
| 62 | EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
|
---|
| 63 | return -1;
|
---|
| 64 | }
|
---|
| 65 | M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
|
---|
| 66 | return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
|
---|
| 70 | {
|
---|
| 71 | int ret;
|
---|
| 72 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
|
---|
| 73 | EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
|
---|
| 74 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 75 | return -2;
|
---|
| 76 | }
|
---|
| 77 | ctx->operation = EVP_PKEY_OP_VERIFY;
|
---|
| 78 | if (!ctx->pmeth->verify_init)
|
---|
| 79 | return 1;
|
---|
| 80 | ret = ctx->pmeth->verify_init(ctx);
|
---|
| 81 | if (ret <= 0)
|
---|
| 82 | ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
---|
| 83 | return ret;
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
|
---|
| 87 | const unsigned char *sig, size_t siglen,
|
---|
| 88 | const unsigned char *tbs, size_t tbslen)
|
---|
| 89 | {
|
---|
| 90 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
|
---|
| 91 | EVPerr(EVP_F_EVP_PKEY_VERIFY,
|
---|
| 92 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 93 | return -2;
|
---|
| 94 | }
|
---|
| 95 | if (ctx->operation != EVP_PKEY_OP_VERIFY) {
|
---|
| 96 | EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
|
---|
| 97 | return -1;
|
---|
| 98 | }
|
---|
| 99 | return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
|
---|
| 103 | {
|
---|
| 104 | int ret;
|
---|
| 105 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
|
---|
| 106 | EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
|
---|
| 107 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 108 | return -2;
|
---|
| 109 | }
|
---|
| 110 | ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
|
---|
| 111 | if (!ctx->pmeth->verify_recover_init)
|
---|
| 112 | return 1;
|
---|
| 113 | ret = ctx->pmeth->verify_recover_init(ctx);
|
---|
| 114 | if (ret <= 0)
|
---|
| 115 | ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
---|
| 116 | return ret;
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
|
---|
| 120 | unsigned char *rout, size_t *routlen,
|
---|
| 121 | const unsigned char *sig, size_t siglen)
|
---|
| 122 | {
|
---|
| 123 | if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
|
---|
| 124 | EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
|
---|
| 125 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 126 | return -2;
|
---|
| 127 | }
|
---|
| 128 | if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
|
---|
| 129 | EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
|
---|
| 130 | return -1;
|
---|
| 131 | }
|
---|
| 132 | M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
|
---|
| 133 | return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
|
---|
| 134 | }
|
---|
| 135 |
|
---|
| 136 | int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
|
---|
| 137 | {
|
---|
| 138 | int ret;
|
---|
| 139 | if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
|
---|
| 140 | EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
|
---|
| 141 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 142 | return -2;
|
---|
| 143 | }
|
---|
| 144 | ctx->operation = EVP_PKEY_OP_ENCRYPT;
|
---|
| 145 | if (!ctx->pmeth->encrypt_init)
|
---|
| 146 | return 1;
|
---|
| 147 | ret = ctx->pmeth->encrypt_init(ctx);
|
---|
| 148 | if (ret <= 0)
|
---|
| 149 | ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
---|
| 150 | return ret;
|
---|
| 151 | }
|
---|
| 152 |
|
---|
| 153 | int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
|
---|
| 154 | unsigned char *out, size_t *outlen,
|
---|
| 155 | const unsigned char *in, size_t inlen)
|
---|
| 156 | {
|
---|
| 157 | if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
|
---|
| 158 | EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
|
---|
| 159 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 160 | return -2;
|
---|
| 161 | }
|
---|
| 162 | if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
|
---|
| 163 | EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
|
---|
| 164 | return -1;
|
---|
| 165 | }
|
---|
| 166 | M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
|
---|
| 167 | return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
|
---|
| 171 | {
|
---|
| 172 | int ret;
|
---|
| 173 | if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
|
---|
| 174 | EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
|
---|
| 175 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 176 | return -2;
|
---|
| 177 | }
|
---|
| 178 | ctx->operation = EVP_PKEY_OP_DECRYPT;
|
---|
| 179 | if (!ctx->pmeth->decrypt_init)
|
---|
| 180 | return 1;
|
---|
| 181 | ret = ctx->pmeth->decrypt_init(ctx);
|
---|
| 182 | if (ret <= 0)
|
---|
| 183 | ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
---|
| 184 | return ret;
|
---|
| 185 | }
|
---|
| 186 |
|
---|
| 187 | int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
|
---|
| 188 | unsigned char *out, size_t *outlen,
|
---|
| 189 | const unsigned char *in, size_t inlen)
|
---|
| 190 | {
|
---|
| 191 | if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
|
---|
| 192 | EVPerr(EVP_F_EVP_PKEY_DECRYPT,
|
---|
| 193 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 194 | return -2;
|
---|
| 195 | }
|
---|
| 196 | if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
|
---|
| 197 | EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
|
---|
| 198 | return -1;
|
---|
| 199 | }
|
---|
| 200 | M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
|
---|
| 201 | return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
---|
| 205 | {
|
---|
| 206 | int ret;
|
---|
| 207 | if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
|
---|
| 208 | EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
|
---|
| 209 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 210 | return -2;
|
---|
| 211 | }
|
---|
| 212 | ctx->operation = EVP_PKEY_OP_DERIVE;
|
---|
| 213 | if (!ctx->pmeth->derive_init)
|
---|
| 214 | return 1;
|
---|
| 215 | ret = ctx->pmeth->derive_init(ctx);
|
---|
| 216 | if (ret <= 0)
|
---|
| 217 | ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
---|
| 218 | return ret;
|
---|
| 219 | }
|
---|
| 220 |
|
---|
| 221 | int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
|
---|
| 222 | {
|
---|
| 223 | int ret;
|
---|
| 224 | if (!ctx || !ctx->pmeth
|
---|
| 225 | || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt)
|
---|
| 226 | || !ctx->pmeth->ctrl) {
|
---|
| 227 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
---|
| 228 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 229 | return -2;
|
---|
| 230 | }
|
---|
| 231 | if (ctx->operation != EVP_PKEY_OP_DERIVE
|
---|
| 232 | && ctx->operation != EVP_PKEY_OP_ENCRYPT
|
---|
| 233 | && ctx->operation != EVP_PKEY_OP_DECRYPT) {
|
---|
| 234 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
---|
| 235 | EVP_R_OPERATON_NOT_INITIALIZED);
|
---|
| 236 | return -1;
|
---|
| 237 | }
|
---|
| 238 |
|
---|
| 239 | ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
|
---|
| 240 |
|
---|
| 241 | if (ret <= 0)
|
---|
| 242 | return ret;
|
---|
| 243 |
|
---|
| 244 | if (ret == 2)
|
---|
| 245 | return 1;
|
---|
| 246 |
|
---|
| 247 | if (!ctx->pkey) {
|
---|
| 248 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
|
---|
| 249 | return -1;
|
---|
| 250 | }
|
---|
| 251 |
|
---|
| 252 | if (ctx->pkey->type != peer->type) {
|
---|
| 253 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES);
|
---|
| 254 | return -1;
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | /*
|
---|
| 258 | * ran@cryptocom.ru: For clarity. The error is if parameters in peer are
|
---|
| 259 | * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
|
---|
| 260 | * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
|
---|
| 261 | * (different key types) is impossible here because it is checked earlier.
|
---|
| 262 | * -2 is OK for us here, as well as 1, so we can check for 0 only.
|
---|
| 263 | */
|
---|
| 264 | if (!EVP_PKEY_missing_parameters(peer) &&
|
---|
| 265 | !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
|
---|
| 266 | EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
|
---|
| 267 | return -1;
|
---|
| 268 | }
|
---|
| 269 |
|
---|
| 270 | EVP_PKEY_free(ctx->peerkey);
|
---|
| 271 | ctx->peerkey = peer;
|
---|
| 272 |
|
---|
| 273 | ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
|
---|
| 274 |
|
---|
| 275 | if (ret <= 0) {
|
---|
| 276 | ctx->peerkey = NULL;
|
---|
| 277 | return ret;
|
---|
| 278 | }
|
---|
| 279 |
|
---|
| 280 | EVP_PKEY_up_ref(peer);
|
---|
| 281 | return 1;
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
|
---|
| 285 | {
|
---|
| 286 | if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
|
---|
| 287 | EVPerr(EVP_F_EVP_PKEY_DERIVE,
|
---|
| 288 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
---|
| 289 | return -2;
|
---|
| 290 | }
|
---|
| 291 | if (ctx->operation != EVP_PKEY_OP_DERIVE) {
|
---|
| 292 | EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
|
---|
| 293 | return -1;
|
---|
| 294 | }
|
---|
| 295 | M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
|
---|
| 296 | return ctx->pmeth->derive(ctx, key, pkeylen);
|
---|
| 297 | }
|
---|