1 /*
2 * Copyright 1995-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 <openssl/evp.h>
11
12 #include <limits.h>
13
14 #include <openssl/digest.h>
15 #include <openssl/err.h>
16
17 #include "internal.h"
18
19
EVP_SignInit_ex(EVP_MD_CTX * ctx,const EVP_MD * type,ENGINE * impl)20 int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) {
21 return EVP_DigestInit_ex(ctx, type, impl);
22 }
23
EVP_SignInit(EVP_MD_CTX * ctx,const EVP_MD * type)24 int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type) {
25 return EVP_DigestInit(ctx, type);
26 }
27
EVP_SignUpdate(EVP_MD_CTX * ctx,const void * data,size_t len)28 int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
29 return EVP_DigestUpdate(ctx, data, len);
30 }
31
EVP_SignFinal(const EVP_MD_CTX * ctx,uint8_t * sig,unsigned * out_sig_len,EVP_PKEY * pkey)32 int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, unsigned *out_sig_len,
33 EVP_PKEY *pkey) {
34 uint8_t m[EVP_MAX_MD_SIZE];
35 unsigned m_len;
36 int ret = 0;
37 EVP_MD_CTX tmp_ctx;
38 EVP_PKEY_CTX *pkctx = NULL;
39 size_t sig_len = EVP_PKEY_size(pkey);
40
41 // Ensure the final result will fit in |unsigned|.
42 if (sig_len > UINT_MAX) {
43 sig_len = UINT_MAX;
44 }
45
46 *out_sig_len = 0;
47 EVP_MD_CTX_init(&tmp_ctx);
48 if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) ||
49 !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) {
50 goto out;
51 }
52 EVP_MD_CTX_cleanup(&tmp_ctx);
53
54 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
55 if (!pkctx || //
56 !EVP_PKEY_sign_init(pkctx) ||
57 !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) ||
58 !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) {
59 goto out;
60 }
61 *out_sig_len = (unsigned)sig_len;
62 ret = 1;
63
64 out:
65 EVP_PKEY_CTX_free(pkctx);
66 return ret;
67 }
68
EVP_VerifyInit_ex(EVP_MD_CTX * ctx,const EVP_MD * type,ENGINE * impl)69 int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) {
70 return EVP_DigestInit_ex(ctx, type, impl);
71 }
72
EVP_VerifyInit(EVP_MD_CTX * ctx,const EVP_MD * type)73 int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type) {
74 return EVP_DigestInit(ctx, type);
75 }
76
EVP_VerifyUpdate(EVP_MD_CTX * ctx,const void * data,size_t len)77 int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
78 return EVP_DigestUpdate(ctx, data, len);
79 }
80
EVP_VerifyFinal(EVP_MD_CTX * ctx,const uint8_t * sig,size_t sig_len,EVP_PKEY * pkey)81 int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len,
82 EVP_PKEY *pkey) {
83 uint8_t m[EVP_MAX_MD_SIZE];
84 unsigned m_len;
85 int ret = 0;
86 EVP_MD_CTX tmp_ctx;
87 EVP_PKEY_CTX *pkctx = NULL;
88
89 EVP_MD_CTX_init(&tmp_ctx);
90 if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) ||
91 !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) {
92 EVP_MD_CTX_cleanup(&tmp_ctx);
93 goto out;
94 }
95 EVP_MD_CTX_cleanup(&tmp_ctx);
96
97 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
98 if (!pkctx ||
99 !EVP_PKEY_verify_init(pkctx) ||
100 !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest)) {
101 goto out;
102 }
103 ret = EVP_PKEY_verify(pkctx, sig, sig_len, m, m_len);
104
105 out:
106 EVP_PKEY_CTX_free(pkctx);
107 return ret;
108 }
109
110