]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/common/ciphers/aes.c
Fix the S390X support for the basic AES ciphers
[thirdparty/openssl.git] / providers / common / ciphers / aes.c
CommitLineData
aab26e6f
MC
1/*
2 * Copyright 2019 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#include <string.h>
11#include <openssl/crypto.h>
12#include <openssl/core_numbers.h>
13#include <openssl/core_names.h>
14#include <openssl/evp.h>
15#include <openssl/params.h>
16#include "internal/cryptlib.h"
861b8f87 17#include "internal/provider_algs.h"
aab26e6f
MC
18#include "ciphers_locl.h"
19
3a7b15e4
MC
20static OSSL_OP_cipher_encrypt_init_fn aes_einit;
21static OSSL_OP_cipher_decrypt_init_fn aes_dinit;
22static OSSL_OP_cipher_update_fn aes_block_update;
23static OSSL_OP_cipher_final_fn aes_block_final;
24static OSSL_OP_cipher_update_fn aes_stream_update;
25static OSSL_OP_cipher_final_fn aes_stream_final;
26static OSSL_OP_cipher_cipher_fn aes_cipher;
27static OSSL_OP_cipher_freectx_fn aes_freectx;
28static OSSL_OP_cipher_dupctx_fn aes_dupctx;
29static OSSL_OP_cipher_key_length_fn key_length_256;
30static OSSL_OP_cipher_key_length_fn key_length_192;
31static OSSL_OP_cipher_key_length_fn key_length_128;
32static OSSL_OP_cipher_iv_length_fn iv_length_16;
33static OSSL_OP_cipher_iv_length_fn iv_length_0;
34static OSSL_OP_cipher_block_size_fn block_size_16;
35static OSSL_OP_cipher_block_size_fn block_size_1;
36static OSSL_OP_cipher_ctx_get_params_fn aes_ctx_get_params;
37static OSSL_OP_cipher_ctx_set_params_fn aes_ctx_set_params;
38
344cfa34 39static int PROV_AES_KEY_generic_init(PROV_AES_KEY *ctx,
aab26e6f 40 const unsigned char *iv,
344cfa34 41 size_t ivlen,
aab26e6f
MC
42 int enc)
43{
344cfa34
MC
44 if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
45 if (ivlen != AES_BLOCK_SIZE)
46 return 0;
aab26e6f 47 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
344cfa34 48 }
aab26e6f 49 ctx->enc = enc;
344cfa34
MC
50
51 return 1;
aab26e6f
MC
52}
53
344cfa34
MC
54static int aes_einit(void *vctx, const unsigned char *key, size_t keylen,
55 const unsigned char *iv, size_t ivlen)
aab26e6f
MC
56{
57 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
58
344cfa34
MC
59 if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 1))
60 return 0;
61 if (key != NULL) {
62 if (keylen != ctx->keylen)
63 return 0;
aab26e6f 64 return ctx->ciph->init(ctx, key, ctx->keylen);
344cfa34 65 }
aab26e6f
MC
66
67 return 1;
68}
69
344cfa34
MC
70static int aes_dinit(void *vctx, const unsigned char *key, size_t keylen,
71 const unsigned char *iv, size_t ivlen)
aab26e6f
MC
72{
73 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
74
344cfa34
MC
75 if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 0))
76 return 0;
77 if (key != NULL) {
78 if (keylen != ctx->keylen)
79 return 0;
aab26e6f 80 return ctx->ciph->init(ctx, key, ctx->keylen);
344cfa34 81 }
aab26e6f
MC
82
83 return 1;
84}
85
ed98df51 86static int aes_block_update(void *vctx, unsigned char *out, size_t *outl,
3b94944c 87 size_t outsize, const unsigned char *in, size_t inl)
aab26e6f
MC
88{
89 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
90 size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in,
91 &inl);
92 size_t outlint = 0;
93
94 /*
95 * If we're decrypting and we end an update on a block boundary we hold
96 * the last block back in case this is the last update call and the last
97 * block is padded.
98 */
99 if (ctx->bufsz == AES_BLOCK_SIZE
100 && (ctx->enc || inl > 0 || !ctx->pad)) {
3b94944c
MC
101 if (outsize < AES_BLOCK_SIZE)
102 return 0;
aab26e6f
MC
103 if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE))
104 return 0;
105 ctx->bufsz = 0;
106 outlint = AES_BLOCK_SIZE;
107 out += AES_BLOCK_SIZE;
108 }
109 if (nextblocks > 0) {
110 if (!ctx->enc && ctx->pad && nextblocks == inl) {
111 if (!ossl_assert(inl >= AES_BLOCK_SIZE))
112 return 0;
113 nextblocks -= AES_BLOCK_SIZE;
114 }
3b94944c
MC
115 outlint += nextblocks;
116 if (outsize < outlint)
117 return 0;
aab26e6f
MC
118 if (!ctx->ciph->cipher(ctx, out, in, nextblocks))
119 return 0;
120 in += nextblocks;
121 inl -= nextblocks;
aab26e6f
MC
122 }
123 if (!trailingdata(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, &inl))
124 return 0;
125
126 *outl = outlint;
127 return inl == 0;
128}
129
3b94944c
MC
130static int aes_block_final(void *vctx, unsigned char *out, size_t *outl,
131 size_t outsize)
aab26e6f
MC
132{
133 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
134
135 if (ctx->enc) {
136 if (ctx->pad) {
137 padblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE);
138 } else if (ctx->bufsz == 0) {
139 *outl = 0;
140 return 1;
141 } else if (ctx->bufsz != AES_BLOCK_SIZE) {
142 /* TODO(3.0): What is the correct error code here? */
143 return 0;
144 }
145
3b94944c
MC
146 if (outsize < AES_BLOCK_SIZE)
147 return 0;
aab26e6f
MC
148 if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE))
149 return 0;
150 ctx->bufsz = 0;
151 *outl = AES_BLOCK_SIZE;
152 return 1;
153 }
154
155 /* Decrypting */
156 /* TODO(3.0): What's the correct error here */
157 if (ctx->bufsz != AES_BLOCK_SIZE) {
158 if (ctx->bufsz == 0 && !ctx->pad) {
159 *outl = 0;
160 return 1;
161 }
162 return 0;
163 }
164
165 if (!ctx->ciph->cipher(ctx, ctx->buf, ctx->buf, AES_BLOCK_SIZE))
166 return 0;
167
168 /* TODO(3.0): What is the correct error here */
169 if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE))
170 return 0;
171
3b94944c
MC
172 if (outsize < ctx->bufsz)
173 return 0;
aab26e6f
MC
174 memcpy(out, ctx->buf, ctx->bufsz);
175 *outl = ctx->bufsz;
176 ctx->bufsz = 0;
177 return 1;
178}
179
ed98df51 180static int aes_stream_update(void *vctx, unsigned char *out, size_t *outl,
3b94944c
MC
181 size_t outsize, const unsigned char *in,
182 size_t inl)
ed98df51
MC
183{
184 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
185
3b94944c
MC
186 if (outsize < inl)
187 return 0;
188
ed98df51
MC
189 if (!ctx->ciph->cipher(ctx, out, in, inl))
190 return 0;
191
192 *outl = inl;
193 return 1;
194}
3b94944c
MC
195static int aes_stream_final(void *vctx, unsigned char *out, size_t *outl,
196 size_t outsize)
ed98df51
MC
197{
198 *outl = 0;
199 return 1;
200}
201
718b133a
MC
202static int aes_cipher(void *vctx, unsigned char *out, const unsigned char *in,
203 size_t inl)
aab26e6f 204{
718b133a
MC
205 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
206
207 if (!ctx->ciph->cipher(ctx, out, in, inl))
208 return 0;
aab26e6f 209
718b133a 210 return 1;
aab26e6f
MC
211}
212
718b133a 213#define IMPLEMENT_new_params(lcmode, UCMODE) \
3a7b15e4 214 static OSSL_OP_cipher_get_params_fn aes_##lcmode##_get_params; \
718b133a
MC
215 static int aes_##lcmode##_get_params(const OSSL_PARAM params[]) \
216 { \
217 const OSSL_PARAM *p; \
218 \
219 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); \
220 if (p != NULL && !OSSL_PARAM_set_int(p, EVP_CIPH_##UCMODE##_MODE)) \
221 return 0; \
222 \
223 return 1; \
224 }
f4a129bb 225
718b133a 226#define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \
3a7b15e4 227 static OSSL_OP_cipher_newctx_fn aes_##len##_##lcmode##_newctx; \
718b133a
MC
228 static void *aes_##len##_##lcmode##_newctx(void) \
229 { \
230 PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
231 \
232 ctx->pad = 1; \
233 ctx->keylen = (len / 8); \
64adf9aa 234 ctx->ciph = PROV_AES_CIPHER_##lcmode(ctx->keylen); \
718b133a
MC
235 ctx->mode = EVP_CIPH_##UCMODE##_MODE; \
236 return ctx; \
237 }
f4a129bb 238
718b133a
MC
239/* ECB */
240IMPLEMENT_new_params(ecb, ECB)
241IMPLEMENT_new_ctx(ecb, ECB, 256)
242IMPLEMENT_new_ctx(ecb, ECB, 192)
243IMPLEMENT_new_ctx(ecb, ECB, 128)
f4a129bb 244
718b133a
MC
245/* CBC */
246IMPLEMENT_new_params(cbc, CBC)
247IMPLEMENT_new_ctx(cbc, CBC, 256)
248IMPLEMENT_new_ctx(cbc, CBC, 192)
249IMPLEMENT_new_ctx(cbc, CBC, 128)
f4a129bb 250
ed98df51
MC
251/* OFB */
252IMPLEMENT_new_params(ofb, OFB)
253IMPLEMENT_new_ctx(ofb, OFB, 256)
254IMPLEMENT_new_ctx(ofb, OFB, 192)
255IMPLEMENT_new_ctx(ofb, OFB, 128)
256
75dd6d64
MC
257/* CFB */
258IMPLEMENT_new_params(cfb, CFB)
259IMPLEMENT_new_params(cfb1, CFB)
260IMPLEMENT_new_params(cfb8, CFB)
261IMPLEMENT_new_ctx(cfb, CFB, 256)
262IMPLEMENT_new_ctx(cfb, CFB, 192)
263IMPLEMENT_new_ctx(cfb, CFB, 128)
264IMPLEMENT_new_ctx(cfb1, CFB, 256)
265IMPLEMENT_new_ctx(cfb1, CFB, 192)
266IMPLEMENT_new_ctx(cfb1, CFB, 128)
267IMPLEMENT_new_ctx(cfb8, CFB, 256)
268IMPLEMENT_new_ctx(cfb8, CFB, 192)
269IMPLEMENT_new_ctx(cfb8, CFB, 128)
ed98df51 270
819a7ae9
MC
271/* CTR */
272IMPLEMENT_new_params(ctr, CTR)
273IMPLEMENT_new_ctx(ctr, CTR, 256)
274IMPLEMENT_new_ctx(ctr, CTR, 192)
275IMPLEMENT_new_ctx(ctr, CTR, 128)
276
aab26e6f
MC
277static void aes_freectx(void *vctx)
278{
279 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
280
281 OPENSSL_clear_free(ctx, sizeof(*ctx));
282}
283
284static void *aes_dupctx(void *ctx)
285{
286 PROV_AES_KEY *in = (PROV_AES_KEY *)ctx;
287 PROV_AES_KEY *ret = OPENSSL_malloc(sizeof(*ret));
288
289 *ret = *in;
290
291 return ret;
292}
293
294static size_t key_length_256(void)
295{
296 return 256 / 8;
297}
298
f4a129bb
MC
299static size_t key_length_192(void)
300{
301 return 192 / 8;
302}
303
304static size_t key_length_128(void)
305{
306 return 128 / 8;
307}
308
718b133a
MC
309static size_t iv_length_16(void)
310{
311 return 16;
312}
313
314static size_t iv_length_0(void)
315{
316 return 0;
317}
318
319static size_t block_size_16(void)
320{
321 return 16;
322}
323
ed98df51
MC
324static size_t block_size_1(void)
325{
326 return 1;
327}
328
718b133a 329static int aes_ctx_get_params(void *vctx, const OSSL_PARAM params[])
aab26e6f
MC
330{
331 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
332 const OSSL_PARAM *p;
333
334 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
335 if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad))
336 return 0;
337
338 return 1;
339}
340
718b133a 341static int aes_ctx_set_params(void *vctx, const OSSL_PARAM params[])
aab26e6f
MC
342{
343 PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
344 const OSSL_PARAM *p;
345
346 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
347 if (p != NULL) {
348 int pad;
349
350 if (!OSSL_PARAM_get_int(p, &pad))
351 return 0;
352 ctx->pad = pad ? 1 : 0;
353 }
354 return 1;
355}
356
ed98df51 357#define IMPLEMENT_block_funcs(mode, keylen, ivlen) \
718b133a
MC
358 const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
359 { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
360 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
361 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
ed98df51
MC
362 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_block_update }, \
363 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_block_final }, \
718b133a
MC
364 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
365 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
366 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
367 { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \
368 { OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \
ed98df51 369 { OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_16 }, \
718b133a
MC
370 { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
371 { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
372 { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
373 { 0, NULL } \
374 };
375
ed98df51
MC
376#define IMPLEMENT_stream_funcs(mode, keylen, ivlen) \
377 const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
378 { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
379 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
380 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
381 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_stream_update }, \
382 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_stream_final }, \
383 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
384 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
385 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
386 { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \
387 { OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \
388 { OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_1 }, \
389 { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
390 { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
391 { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
392 { 0, NULL } \
393 };
718b133a 394
ed98df51
MC
395/* ECB */
396IMPLEMENT_block_funcs(ecb, 256, 0)
397IMPLEMENT_block_funcs(ecb, 192, 0)
398IMPLEMENT_block_funcs(ecb, 128, 0)
718b133a
MC
399
400/* CBC */
ed98df51
MC
401IMPLEMENT_block_funcs(cbc, 256, 16)
402IMPLEMENT_block_funcs(cbc, 192, 16)
403IMPLEMENT_block_funcs(cbc, 128, 16)
404
405/* OFB */
406IMPLEMENT_stream_funcs(ofb, 256, 16)
407IMPLEMENT_stream_funcs(ofb, 192, 16)
408IMPLEMENT_stream_funcs(ofb, 128, 16)
75dd6d64
MC
409
410/* CFB */
411IMPLEMENT_stream_funcs(cfb, 256, 16)
412IMPLEMENT_stream_funcs(cfb, 192, 16)
413IMPLEMENT_stream_funcs(cfb, 128, 16)
414IMPLEMENT_stream_funcs(cfb1, 256, 16)
415IMPLEMENT_stream_funcs(cfb1, 192, 16)
416IMPLEMENT_stream_funcs(cfb1, 128, 16)
417IMPLEMENT_stream_funcs(cfb8, 256, 16)
418IMPLEMENT_stream_funcs(cfb8, 192, 16)
419IMPLEMENT_stream_funcs(cfb8, 128, 16)
819a7ae9
MC
420
421/* CTR */
422IMPLEMENT_stream_funcs(ctr, 256, 16)
423IMPLEMENT_stream_funcs(ctr, 192, 16)
424IMPLEMENT_stream_funcs(ctr, 128, 16)