Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/demos/cipher/aeskeywrap.c
106879 views
1
/*
2
* Copyright 2022-2024 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
* Simple aes wrap encryption demonstration program.
12
*/
13
14
#include <stdio.h>
15
#include <openssl/err.h>
16
#include <openssl/bio.h>
17
#include <openssl/evp.h>
18
#include <openssl/crypto.h>
19
#include <openssl/core_names.h>
20
21
/* aes key */
22
static const unsigned char wrap_key[] = {
23
0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66,
24
0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69,
25
0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f
26
};
27
28
/* Unique initialisation vector */
29
static const unsigned char wrap_iv[] = {
30
0x99,
31
0xaa,
32
0x3e,
33
0x68,
34
0xed,
35
0x81,
36
0x73,
37
0xa0,
38
0xee,
39
0xd0,
40
0x66,
41
0x84,
42
0x99,
43
0xaa,
44
0x3e,
45
0x68,
46
};
47
48
/* Example plaintext to encrypt */
49
static const unsigned char wrap_pt[] = {
50
0xad,
51
0x4f,
52
0xc9,
53
0xfc,
54
0x77,
55
0x69,
56
0xc9,
57
0xea,
58
0xfc,
59
0xdf,
60
0x00,
61
0xac,
62
0x34,
63
0xec,
64
0x40,
65
0xbc,
66
0x28,
67
0x3f,
68
0xa4,
69
0x5e,
70
0xd8,
71
0x99,
72
0xe4,
73
0x5d,
74
0x5e,
75
0x7a,
76
0xc4,
77
0xe6,
78
0xca,
79
0x7b,
80
0xa5,
81
0xb7,
82
};
83
84
/* Expected ciphertext value */
85
static const unsigned char wrap_ct[] = {
86
0x97,
87
0x99,
88
0x55,
89
0xca,
90
0xf6,
91
0x3e,
92
0x95,
93
0x54,
94
0x39,
95
0xd6,
96
0xaf,
97
0x63,
98
0xff,
99
0x2c,
100
0xe3,
101
0x96,
102
0xf7,
103
0x0d,
104
0x2c,
105
0x9c,
106
0xc7,
107
0x43,
108
0xc0,
109
0xb6,
110
0x31,
111
0x43,
112
0xb9,
113
0x20,
114
0xac,
115
0x6b,
116
0xd3,
117
0x67,
118
0xad,
119
0x01,
120
0xaf,
121
0xa7,
122
0x32,
123
0x74,
124
0x26,
125
0x92,
126
};
127
128
/*
129
* A library context and property query can be used to select & filter
130
* algorithm implementations. If they are NULL then the default library
131
* context and properties are used.
132
*/
133
static OSSL_LIB_CTX *libctx = NULL;
134
static const char *propq = NULL;
135
136
static int aes_wrap_encrypt(void)
137
{
138
int ret = 0;
139
EVP_CIPHER_CTX *ctx;
140
EVP_CIPHER *cipher = NULL;
141
int outlen, tmplen;
142
unsigned char outbuf[1024];
143
144
printf("aes wrap Encrypt:\n");
145
printf("Plaintext:\n");
146
BIO_dump_fp(stdout, wrap_pt, sizeof(wrap_pt));
147
148
/* Create a context for the encrypt operation */
149
if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
150
goto err;
151
152
EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
153
154
/* Fetch the cipher implementation */
155
if ((cipher = EVP_CIPHER_fetch(libctx, "AES-256-WRAP", propq)) == NULL)
156
goto err;
157
158
/*
159
* Initialise an encrypt operation with the cipher/mode, key and IV.
160
* We are not setting any custom params so let params be just NULL.
161
*/
162
if (!EVP_EncryptInit_ex2(ctx, cipher, wrap_key, wrap_iv, /* params */ NULL))
163
goto err;
164
165
/* Encrypt plaintext */
166
if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, wrap_pt, sizeof(wrap_pt)))
167
goto err;
168
169
/* Finalise: there can be some additional output from padding */
170
if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen))
171
goto err;
172
outlen += tmplen;
173
174
/* Output encrypted block */
175
printf("Ciphertext (outlen:%d):\n", outlen);
176
BIO_dump_fp(stdout, outbuf, outlen);
177
178
if (sizeof(wrap_ct) == outlen && !CRYPTO_memcmp(outbuf, wrap_ct, outlen))
179
printf("Final ciphertext matches expected ciphertext\n");
180
else
181
printf("Final ciphertext differs from expected ciphertext\n");
182
183
ret = 1;
184
err:
185
if (!ret)
186
ERR_print_errors_fp(stderr);
187
188
EVP_CIPHER_free(cipher);
189
EVP_CIPHER_CTX_free(ctx);
190
191
return ret;
192
}
193
194
static int aes_wrap_decrypt(void)
195
{
196
int ret = 0;
197
EVP_CIPHER_CTX *ctx;
198
EVP_CIPHER *cipher = NULL;
199
int outlen, tmplen;
200
unsigned char outbuf[1024];
201
202
printf("aes wrap Decrypt:\n");
203
printf("Ciphertext:\n");
204
BIO_dump_fp(stdout, wrap_ct, sizeof(wrap_ct));
205
206
if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
207
goto err;
208
209
EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
210
211
/* Fetch the cipher implementation */
212
if ((cipher = EVP_CIPHER_fetch(libctx, "aes-256-wrap", propq)) == NULL)
213
goto err;
214
215
/*
216
* Initialise an encrypt operation with the cipher/mode, key and IV.
217
* We are not setting any custom params so let params be just NULL.
218
*/
219
if (!EVP_DecryptInit_ex2(ctx, cipher, wrap_key, wrap_iv, /* params */ NULL))
220
goto err;
221
222
/* Decrypt plaintext */
223
if (!EVP_DecryptUpdate(ctx, outbuf, &outlen, wrap_ct, sizeof(wrap_ct)))
224
goto err;
225
226
/* Finalise: there can be some additional output from padding */
227
if (!EVP_DecryptFinal_ex(ctx, outbuf + outlen, &tmplen))
228
goto err;
229
outlen += tmplen;
230
231
/* Output decrypted block */
232
printf("Plaintext (outlen:%d):\n", outlen);
233
BIO_dump_fp(stdout, outbuf, outlen);
234
235
if (sizeof(wrap_pt) == outlen && !CRYPTO_memcmp(outbuf, wrap_pt, outlen))
236
printf("Final plaintext matches original plaintext\n");
237
else
238
printf("Final plaintext differs from original plaintext\n");
239
240
ret = 1;
241
err:
242
if (!ret)
243
ERR_print_errors_fp(stderr);
244
245
EVP_CIPHER_free(cipher);
246
EVP_CIPHER_CTX_free(ctx);
247
248
return ret;
249
}
250
251
int main(int argc, char **argv)
252
{
253
if (!aes_wrap_encrypt())
254
return EXIT_FAILURE;
255
256
if (!aes_wrap_decrypt())
257
return EXIT_FAILURE;
258
259
return EXIT_SUCCESS;
260
}
261
262