]>
Commit | Line | Data |
---|---|---|
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 | ||
20 | static void PROV_AES_KEY_generic_init(PROV_AES_KEY *ctx, | |
21 | const unsigned char *iv, | |
22 | int enc) | |
23 | { | |
24 | if (iv != NULL) | |
25 | memcpy(ctx->iv, iv, AES_BLOCK_SIZE); | |
26 | ctx->enc = enc; | |
27 | } | |
28 | ||
29 | static int aes_einit(void *vctx, const unsigned char *key, | |
30 | const unsigned char *iv) | |
31 | { | |
32 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
33 | ||
34 | PROV_AES_KEY_generic_init(ctx, iv, 1); | |
35 | if (key != NULL) | |
36 | return ctx->ciph->init(ctx, key, ctx->keylen); | |
37 | ||
38 | return 1; | |
39 | } | |
40 | ||
41 | static int aes_dinit(void *vctx, const unsigned char *key, | |
42 | const unsigned char *iv) | |
43 | { | |
44 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
45 | ||
46 | PROV_AES_KEY_generic_init(ctx, iv, 0); | |
47 | if (key != NULL) | |
48 | return ctx->ciph->init(ctx, key, ctx->keylen); | |
49 | ||
50 | return 1; | |
51 | } | |
52 | ||
53 | static int aes_update(void *vctx, unsigned char *out, size_t *outl, | |
54 | const unsigned char *in, size_t inl) | |
55 | { | |
56 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
57 | size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, | |
58 | &inl); | |
59 | size_t outlint = 0; | |
60 | ||
61 | /* | |
62 | * If we're decrypting and we end an update on a block boundary we hold | |
63 | * the last block back in case this is the last update call and the last | |
64 | * block is padded. | |
65 | */ | |
66 | if (ctx->bufsz == AES_BLOCK_SIZE | |
67 | && (ctx->enc || inl > 0 || !ctx->pad)) { | |
68 | if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) | |
69 | return 0; | |
70 | ctx->bufsz = 0; | |
71 | outlint = AES_BLOCK_SIZE; | |
72 | out += AES_BLOCK_SIZE; | |
73 | } | |
74 | if (nextblocks > 0) { | |
75 | if (!ctx->enc && ctx->pad && nextblocks == inl) { | |
76 | if (!ossl_assert(inl >= AES_BLOCK_SIZE)) | |
77 | return 0; | |
78 | nextblocks -= AES_BLOCK_SIZE; | |
79 | } | |
80 | if (!ctx->ciph->cipher(ctx, out, in, nextblocks)) | |
81 | return 0; | |
82 | in += nextblocks; | |
83 | inl -= nextblocks; | |
84 | outlint += nextblocks; | |
85 | } | |
86 | if (!trailingdata(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, &inl)) | |
87 | return 0; | |
88 | ||
89 | *outl = outlint; | |
90 | return inl == 0; | |
91 | } | |
92 | ||
93 | static int aes_final(void *vctx, unsigned char *out, size_t *outl) | |
94 | { | |
95 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
96 | ||
97 | if (ctx->enc) { | |
98 | if (ctx->pad) { | |
99 | padblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE); | |
100 | } else if (ctx->bufsz == 0) { | |
101 | *outl = 0; | |
102 | return 1; | |
103 | } else if (ctx->bufsz != AES_BLOCK_SIZE) { | |
104 | /* TODO(3.0): What is the correct error code here? */ | |
105 | return 0; | |
106 | } | |
107 | ||
108 | if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) | |
109 | return 0; | |
110 | ctx->bufsz = 0; | |
111 | *outl = AES_BLOCK_SIZE; | |
112 | return 1; | |
113 | } | |
114 | ||
115 | /* Decrypting */ | |
116 | /* TODO(3.0): What's the correct error here */ | |
117 | if (ctx->bufsz != AES_BLOCK_SIZE) { | |
118 | if (ctx->bufsz == 0 && !ctx->pad) { | |
119 | *outl = 0; | |
120 | return 1; | |
121 | } | |
122 | return 0; | |
123 | } | |
124 | ||
125 | if (!ctx->ciph->cipher(ctx, ctx->buf, ctx->buf, AES_BLOCK_SIZE)) | |
126 | return 0; | |
127 | ||
128 | /* TODO(3.0): What is the correct error here */ | |
129 | if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE)) | |
130 | return 0; | |
131 | ||
132 | memcpy(out, ctx->buf, ctx->bufsz); | |
133 | *outl = ctx->bufsz; | |
134 | ctx->bufsz = 0; | |
135 | return 1; | |
136 | } | |
137 | ||
138 | static void *aes_256_ecb_newctx(void) | |
139 | { | |
140 | PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
141 | ||
142 | ctx->pad = 1; | |
143 | ctx->keylen = 256 / 8; | |
144 | ctx->ciph = PROV_AES_CIPHER_ecb(); | |
145 | ctx->mode = EVP_CIPH_ECB_MODE; | |
146 | return ctx; | |
147 | } | |
148 | ||
f4a129bb MC |
149 | static void *aes_192_ecb_newctx(void) |
150 | { | |
151 | PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
152 | ||
153 | ctx->pad = 1; | |
154 | ctx->keylen = 192 / 8; | |
155 | ctx->ciph = PROV_AES_CIPHER_ecb(); | |
156 | ctx->mode = EVP_CIPH_ECB_MODE; | |
157 | return ctx; | |
158 | } | |
159 | ||
160 | static void *aes_128_ecb_newctx(void) | |
161 | { | |
162 | PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
163 | ||
164 | ctx->pad = 1; | |
165 | ctx->keylen = 128 / 8; | |
166 | ctx->ciph = PROV_AES_CIPHER_ecb(); | |
167 | ctx->mode = EVP_CIPH_ECB_MODE; | |
168 | return ctx; | |
169 | } | |
170 | ||
aab26e6f MC |
171 | static void aes_freectx(void *vctx) |
172 | { | |
173 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
174 | ||
175 | OPENSSL_clear_free(ctx, sizeof(*ctx)); | |
176 | } | |
177 | ||
178 | static void *aes_dupctx(void *ctx) | |
179 | { | |
180 | PROV_AES_KEY *in = (PROV_AES_KEY *)ctx; | |
181 | PROV_AES_KEY *ret = OPENSSL_malloc(sizeof(*ret)); | |
182 | ||
183 | *ret = *in; | |
184 | ||
185 | return ret; | |
186 | } | |
187 | ||
188 | static size_t key_length_256(void) | |
189 | { | |
190 | return 256 / 8; | |
191 | } | |
192 | ||
f4a129bb MC |
193 | static size_t key_length_192(void) |
194 | { | |
195 | return 192 / 8; | |
196 | } | |
197 | ||
198 | static size_t key_length_128(void) | |
199 | { | |
200 | return 128 / 8; | |
201 | } | |
202 | ||
aab26e6f MC |
203 | static int aes_get_params(void *vctx, const OSSL_PARAM params[]) |
204 | { | |
205 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
206 | const OSSL_PARAM *p; | |
207 | ||
208 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); | |
209 | if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) | |
210 | return 0; | |
211 | ||
212 | return 1; | |
213 | } | |
214 | ||
215 | static int aes_set_params(void *vctx, const OSSL_PARAM params[]) | |
216 | { | |
217 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
218 | const OSSL_PARAM *p; | |
219 | ||
220 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); | |
221 | if (p != NULL) { | |
222 | int pad; | |
223 | ||
224 | if (!OSSL_PARAM_get_int(p, &pad)) | |
225 | return 0; | |
226 | ctx->pad = pad ? 1 : 0; | |
227 | } | |
228 | return 1; | |
229 | } | |
230 | ||
aab26e6f MC |
231 | const OSSL_DISPATCH aes256ecb_functions[] = { |
232 | { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_256_ecb_newctx }, | |
233 | { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, | |
234 | { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, | |
235 | { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_update }, | |
236 | { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_final }, | |
237 | { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, | |
238 | { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, | |
239 | { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_256 }, | |
240 | { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_get_params }, | |
241 | { OSSL_FUNC_CIPHER_SET_PARAMS, (void (*)(void))aes_set_params }, | |
242 | { 0, NULL } | |
243 | }; | |
f4a129bb MC |
244 | |
245 | const OSSL_DISPATCH aes192ecb_functions[] = { | |
246 | { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_192_ecb_newctx }, | |
247 | { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, | |
248 | { OSSL_FUNC_CIPHER_ENCRYPT_UPDATE, (void (*)(void))aes_update }, | |
249 | { OSSL_FUNC_CIPHER_ENCRYPT_FINAL, (void (*)(void))aes_efinal }, | |
250 | { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, | |
251 | { OSSL_FUNC_CIPHER_DECRYPT_UPDATE, (void (*)(void))aes_update }, | |
252 | { OSSL_FUNC_CIPHER_DECRYPT_FINAL, (void (*)(void))aes_dfinal }, | |
253 | { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, | |
254 | { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, | |
255 | { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_192 }, | |
256 | { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_get_params }, | |
257 | { OSSL_FUNC_CIPHER_SET_PARAMS, (void (*)(void))aes_set_params }, | |
258 | { 0, NULL } | |
259 | }; | |
260 | ||
261 | const OSSL_DISPATCH aes128ecb_functions[] = { | |
262 | { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_128_ecb_newctx }, | |
263 | { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, | |
264 | { OSSL_FUNC_CIPHER_ENCRYPT_UPDATE, (void (*)(void))aes_update }, | |
265 | { OSSL_FUNC_CIPHER_ENCRYPT_FINAL, (void (*)(void))aes_efinal }, | |
266 | { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, | |
267 | { OSSL_FUNC_CIPHER_DECRYPT_UPDATE, (void (*)(void))aes_update }, | |
268 | { OSSL_FUNC_CIPHER_DECRYPT_FINAL, (void (*)(void))aes_dfinal }, | |
269 | { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, | |
270 | { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, | |
271 | { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_128 }, | |
272 | { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_get_params }, | |
273 | { OSSL_FUNC_CIPHER_SET_PARAMS, (void (*)(void))aes_set_params }, | |
274 | { 0, NULL } | |
275 | }; |