2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
12 #include <openssl/core_names.h>
13 #include <openssl/evp.h>
14 #include <openssl/rsa.h>
15 #include <openssl/params.h>
16 #include <openssl/err.h>
17 #include <openssl/bio.h>
20 /* The data to be signed. This will be hashed. */
21 static const char test_message
[] =
22 "This is an example message to be signed.";
24 /* A property query used for selecting algorithm implementations. */
25 static const char *propq
= NULL
;
28 * This function demonstrates RSA signing of an arbitrary-length message.
29 * Hashing is performed automatically. In this example, SHA-256 is used. If you
30 * have already hashed your message and simply want to sign the hash directly,
31 * see rsa_pss_direct.c.
33 static int sign(OSSL_LIB_CTX
*libctx
, unsigned char **sig
, size_t *sig_len
)
36 EVP_PKEY
*pkey
= NULL
;
37 EVP_MD_CTX
*mctx
= NULL
;
38 OSSL_PARAM params
[2], *p
= params
;
39 const unsigned char *ppriv_key
= NULL
;
43 /* Load DER-encoded RSA private key. */
44 ppriv_key
= rsa_priv_key
;
45 pkey
= d2i_PrivateKey_ex(EVP_PKEY_RSA
, NULL
, &ppriv_key
,
46 sizeof(rsa_priv_key
), libctx
, propq
);
48 fprintf(stderr
, "Failed to load private key\n");
52 /* Create MD context used for signing. */
53 mctx
= EVP_MD_CTX_new();
55 fprintf(stderr
, "Failed to create MD context\n");
59 /* Initialize MD context for signing. */
60 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE
,
61 OSSL_PKEY_RSA_PAD_MODE_PSS
, 0);
62 *p
= OSSL_PARAM_construct_end();
64 if (EVP_DigestSignInit_ex(mctx
, NULL
, "SHA256", libctx
, propq
,
66 fprintf(stderr
, "Failed to initialize signing context\n");
71 * Feed data to be signed into the algorithm. This may
72 * be called multiple times.
74 if (EVP_DigestSignUpdate(mctx
, test_message
, sizeof(test_message
)) == 0) {
75 fprintf(stderr
, "Failed to hash message into signing context\n");
79 /* Determine signature length. */
80 if (EVP_DigestSignFinal(mctx
, NULL
, sig_len
) == 0) {
81 fprintf(stderr
, "Failed to get signature length\n");
85 /* Allocate memory for signature. */
86 *sig
= OPENSSL_malloc(*sig_len
);
88 fprintf(stderr
, "Failed to allocate memory for signature\n");
92 /* Generate signature. */
93 if (EVP_DigestSignFinal(mctx
, *sig
, sig_len
) == 0) {
94 fprintf(stderr
, "Failed to sign\n");
100 EVP_MD_CTX_free(mctx
);
110 * This function demonstrates verification of an RSA signature over an
111 * arbitrary-length message using the PSS signature scheme. Hashing is performed
114 static int verify(OSSL_LIB_CTX
*libctx
, const unsigned char *sig
, size_t sig_len
)
117 EVP_PKEY
*pkey
= NULL
;
118 EVP_MD_CTX
*mctx
= NULL
;
119 OSSL_PARAM params
[2], *p
= params
;
120 const unsigned char *ppub_key
= NULL
;
122 /* Load DER-encoded RSA public key. */
123 ppub_key
= rsa_pub_key
;
124 pkey
= d2i_PublicKey(EVP_PKEY_RSA
, NULL
, &ppub_key
, sizeof(rsa_pub_key
));
126 fprintf(stderr
, "Failed to load public key\n");
130 /* Create MD context used for verification. */
131 mctx
= EVP_MD_CTX_new();
133 fprintf(stderr
, "Failed to create MD context\n");
137 /* Initialize MD context for verification. */
138 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE
,
139 OSSL_PKEY_RSA_PAD_MODE_PSS
, 0);
140 *p
= OSSL_PARAM_construct_end();
142 if (EVP_DigestVerifyInit_ex(mctx
, NULL
, "SHA256", libctx
, propq
,
143 pkey
, params
) == 0) {
144 fprintf(stderr
, "Failed to initialize signing context\n");
149 * Feed data to be signed into the algorithm. This may
150 * be called multiple times.
152 if (EVP_DigestVerifyUpdate(mctx
, test_message
, sizeof(test_message
)) == 0) {
153 fprintf(stderr
, "Failed to hash message into signing context\n");
157 /* Verify signature. */
158 if (EVP_DigestVerifyFinal(mctx
, sig
, sig_len
) == 0) {
159 fprintf(stderr
, "Failed to verify signature; "
160 "signature may be invalid\n");
166 EVP_MD_CTX_free(mctx
);
171 int main(int argc
, char **argv
)
174 OSSL_LIB_CTX
*libctx
= NULL
;
175 unsigned char *sig
= NULL
;
178 if (sign(libctx
, &sig
, &sig_len
) == 0)
181 if (verify(libctx
, sig
, sig_len
) == 0)
187 OSSL_LIB_CTX_free(libctx
);