VirtualBox

source: vbox/trunk/src/libs/openssl-3.3.2/demos/encrypt/rsa_encrypt.c@ 108358

最後變更 在這個檔案從108358是 108206,由 vboxsync 提交於 5 週 前

openssl-3.3.2: Exported all files to OSE and removed .scm-settings ​bugref:10757

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.7 KB
 
1/*-
2 * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10/*
11 * An example that uses EVP_PKEY_encrypt and EVP_PKEY_decrypt methods
12 * to encrypt and decrypt data using an RSA keypair.
13 * RSA encryption produces different encrypted output each time it is run,
14 * hence this is not a known answer test.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <openssl/err.h>
20#include <openssl/evp.h>
21#include <openssl/decoder.h>
22#include <openssl/core_names.h>
23#include "rsa_encrypt.h"
24
25/* Input data to encrypt */
26static const unsigned char msg[] =
27 "To be, or not to be, that is the question,\n"
28 "Whether tis nobler in the minde to suffer\n"
29 "The slings and arrowes of outragious fortune,\n"
30 "Or to take Armes again in a sea of troubles";
31
32/*
33 * For do_encrypt(), load an RSA public key from pub_key_der[].
34 * For do_decrypt(), load an RSA private key from priv_key_der[].
35 */
36static EVP_PKEY *get_key(OSSL_LIB_CTX *libctx, const char *propq, int public)
37{
38 OSSL_DECODER_CTX *dctx = NULL;
39 EVP_PKEY *pkey = NULL;
40 int selection;
41 const unsigned char *data;
42 size_t data_len;
43
44 if (public) {
45 selection = EVP_PKEY_PUBLIC_KEY;
46 data = pub_key_der;
47 data_len = sizeof(pub_key_der);
48 } else {
49 selection = EVP_PKEY_KEYPAIR;
50 data = priv_key_der;
51 data_len = sizeof(priv_key_der);
52 }
53 dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, "RSA",
54 selection, libctx, propq);
55 (void)OSSL_DECODER_from_data(dctx, &data, &data_len);
56 OSSL_DECODER_CTX_free(dctx);
57 return pkey;
58}
59
60/* Set optional parameters for RSA OAEP Padding */
61static void set_optional_params(OSSL_PARAM *p, const char *propq)
62{
63 static unsigned char label[] = "label";
64
65 /* "pkcs1" is used by default if the padding mode is not set */
66 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE,
67 OSSL_PKEY_RSA_PAD_MODE_OAEP, 0);
68 /* No oaep_label is used if this is not set */
69 *p++ = OSSL_PARAM_construct_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL,
70 label, sizeof(label));
71 /* "SHA1" is used if this is not set */
72 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST,
73 "SHA256", 0);
74 /*
75 * If a non default property query needs to be specified when fetching the
76 * OAEP digest then it needs to be specified here.
77 */
78 if (propq != NULL)
79 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS,
80 (char *)propq, 0);
81
82 /*
83 * OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST and
84 * OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS can also be optionally added
85 * here if the MGF1 digest differs from the OAEP digest.
86 */
87
88 *p = OSSL_PARAM_construct_end();
89}
90
91/*
92 * The length of the input data that can be encrypted is limited by the
93 * RSA key length minus some additional bytes that depends on the padding mode.
94 *
95 */
96static int do_encrypt(OSSL_LIB_CTX *libctx,
97 const unsigned char *in, size_t in_len,
98 unsigned char **out, size_t *out_len)
99{
100 int ret = 0, public = 1;
101 size_t buf_len = 0;
102 unsigned char *buf = NULL;
103 const char *propq = NULL;
104 EVP_PKEY_CTX *ctx = NULL;
105 EVP_PKEY *pub_key = NULL;
106 OSSL_PARAM params[5];
107
108 /* Get public key */
109 pub_key = get_key(libctx, propq, public);
110 if (pub_key == NULL) {
111 fprintf(stderr, "Get public key failed.\n");
112 goto cleanup;
113 }
114 ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pub_key, propq);
115 if (ctx == NULL) {
116 fprintf(stderr, "EVP_PKEY_CTX_new_from_pkey() failed.\n");
117 goto cleanup;
118 }
119 set_optional_params(params, propq);
120 /* If no optional parameters are required then NULL can be passed */
121 if (EVP_PKEY_encrypt_init_ex(ctx, params) <= 0) {
122 fprintf(stderr, "EVP_PKEY_encrypt_init_ex() failed.\n");
123 goto cleanup;
124 }
125 /* Calculate the size required to hold the encrypted data */
126 if (EVP_PKEY_encrypt(ctx, NULL, &buf_len, in, in_len) <= 0) {
127 fprintf(stderr, "EVP_PKEY_encrypt() failed.\n");
128 goto cleanup;
129 }
130 buf = OPENSSL_zalloc(buf_len);
131 if (buf == NULL) {
132 fprintf(stderr, "Malloc failed.\n");
133 goto cleanup;
134 }
135 if (EVP_PKEY_encrypt(ctx, buf, &buf_len, in, in_len) <= 0) {
136 fprintf(stderr, "EVP_PKEY_encrypt() failed.\n");
137 goto cleanup;
138 }
139 *out_len = buf_len;
140 *out = buf;
141 fprintf(stdout, "Encrypted:\n");
142 BIO_dump_indent_fp(stdout, buf, buf_len, 2);
143 fprintf(stdout, "\n");
144 ret = 1;
145
146cleanup:
147 if (!ret)
148 OPENSSL_free(buf);
149 EVP_PKEY_free(pub_key);
150 EVP_PKEY_CTX_free(ctx);
151 return ret;
152}
153
154static int do_decrypt(OSSL_LIB_CTX *libctx, const unsigned char *in, size_t in_len,
155 unsigned char **out, size_t *out_len)
156{
157 int ret = 0, public = 0;
158 size_t buf_len = 0;
159 unsigned char *buf = NULL;
160 const char *propq = NULL;
161 EVP_PKEY_CTX *ctx = NULL;
162 EVP_PKEY *priv_key = NULL;
163 OSSL_PARAM params[5];
164
165 /* Get private key */
166 priv_key = get_key(libctx, propq, public);
167 if (priv_key == NULL) {
168 fprintf(stderr, "Get private key failed.\n");
169 goto cleanup;
170 }
171 ctx = EVP_PKEY_CTX_new_from_pkey(libctx, priv_key, propq);
172 if (ctx == NULL) {
173 fprintf(stderr, "EVP_PKEY_CTX_new_from_pkey() failed.\n");
174 goto cleanup;
175 }
176
177 /* The parameters used for encryption must also be used for decryption */
178 set_optional_params(params, propq);
179 /* If no optional parameters are required then NULL can be passed */
180 if (EVP_PKEY_decrypt_init_ex(ctx, params) <= 0) {
181 fprintf(stderr, "EVP_PKEY_decrypt_init_ex() failed.\n");
182 goto cleanup;
183 }
184 /* Calculate the size required to hold the decrypted data */
185 if (EVP_PKEY_decrypt(ctx, NULL, &buf_len, in, in_len) <= 0) {
186 fprintf(stderr, "EVP_PKEY_decrypt() failed.\n");
187 goto cleanup;
188 }
189 buf = OPENSSL_zalloc(buf_len);
190 if (buf == NULL) {
191 fprintf(stderr, "Malloc failed.\n");
192 goto cleanup;
193 }
194 if (EVP_PKEY_decrypt(ctx, buf, &buf_len, in, in_len) <= 0) {
195 fprintf(stderr, "EVP_PKEY_decrypt() failed.\n");
196 goto cleanup;
197 }
198 *out_len = buf_len;
199 *out = buf;
200 fprintf(stdout, "Decrypted:\n");
201 BIO_dump_indent_fp(stdout, buf, buf_len, 2);
202 fprintf(stdout, "\n");
203 ret = 1;
204
205cleanup:
206 if (!ret)
207 OPENSSL_free(buf);
208 EVP_PKEY_free(priv_key);
209 EVP_PKEY_CTX_free(ctx);
210 return ret;
211}
212
213int main(void)
214{
215 int ret = EXIT_FAILURE;
216 size_t msg_len = sizeof(msg) - 1;
217 size_t encrypted_len = 0, decrypted_len = 0;
218 unsigned char *encrypted = NULL, *decrypted = NULL;
219 OSSL_LIB_CTX *libctx = NULL;
220
221 if (!do_encrypt(libctx, msg, msg_len, &encrypted, &encrypted_len)) {
222 fprintf(stderr, "encryption failed.\n");
223 goto cleanup;
224 }
225 if (!do_decrypt(libctx, encrypted, encrypted_len,
226 &decrypted, &decrypted_len)) {
227 fprintf(stderr, "decryption failed.\n");
228 goto cleanup;
229 }
230 if (CRYPTO_memcmp(msg, decrypted, decrypted_len) != 0) {
231 fprintf(stderr, "Decrypted data does not match expected value\n");
232 goto cleanup;
233 }
234 ret = EXIT_SUCCESS;
235
236cleanup:
237 OPENSSL_free(decrypted);
238 OPENSSL_free(encrypted);
239 OSSL_LIB_CTX_free(libctx);
240 if (ret != EXIT_SUCCESS)
241 ERR_print_errors_fp(stderr);
242 return ret;
243}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette