]> git.ipfire.org Git - thirdparty/openssl.git/blob - ssl/record/methods/ssl3_meth.c
Move the SSLv3 crypto code into the new record layer
[thirdparty/openssl.git] / ssl / record / methods / ssl3_meth.c
1 /*
2 * Copyright 2022 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 <openssl/evp.h>
11 #include <openssl/core_names.h>
12 #include "../../ssl_local.h"
13 #include "../record_local.h"
14 #include "recmethod_local.h"
15
16 static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
17 unsigned char *key, size_t keylen,
18 unsigned char *iv, size_t ivlen,
19 unsigned char *mackey, size_t mackeylen,
20 const EVP_CIPHER *ciph,
21 size_t taglen,
22 int mactype,
23 const EVP_MD *md,
24 COMP_METHOD *comp)
25 {
26 EVP_CIPHER_CTX *ciph_ctx;
27 int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0;
28
29 if (md == NULL) {
30 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
31 return OSSL_RECORD_RETURN_FATAL;
32 }
33
34 if ((rl->enc_ctx = EVP_CIPHER_CTX_new()) == NULL) {
35 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
36 return OSSL_RECORD_RETURN_FATAL;
37 }
38 ciph_ctx = rl->enc_ctx;
39
40 rl->md_ctx = EVP_MD_CTX_new();
41 if (rl->md_ctx == NULL) {
42 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
43 return OSSL_RECORD_RETURN_FATAL;
44 }
45
46 if ((md != NULL && EVP_DigestInit_ex(rl->md_ctx, md, NULL) <= 0)) {
47 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
48 return OSSL_RECORD_RETURN_FATAL;
49 }
50
51 #ifndef OPENSSL_NO_COMP
52 if (comp != NULL) {
53 rl->compctx = COMP_CTX_new(comp);
54 if (rl->compctx == NULL) {
55 ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR);
56 return OSSL_RECORD_RETURN_FATAL;
57 }
58 }
59 #endif
60
61 if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, iv, enc)) {
62 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
63 return OSSL_RECORD_RETURN_FATAL;
64 }
65
66 if (EVP_CIPHER_get0_provider(ciph) != NULL
67 && !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md)) {
68 /* ERR_raise already called */
69 return OSSL_RECORD_RETURN_FATAL;
70 }
71
72 if (mackeylen > sizeof(rl->mac_secret)) {
73 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
74 return OSSL_RECORD_RETURN_FATAL;
75 }
76 memcpy(rl->mac_secret, mackey, mackeylen);
77
78 return OSSL_RECORD_RETURN_SUCCESS;
79 }
80
81 /*
82 * ssl3_cipher encrypts/decrypts |n_recs| records in |inrecs|. Calls RLAYERfatal
83 * on internal error, but not otherwise. It is the responsibility of the caller
84 * to report a bad_record_mac
85 *
86 * Returns:
87 * 0: if the record is publicly invalid, or an internal error
88 * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised)
89 */
90 static int ssl3_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
91 int sending, SSL_MAC_BUF *mac, size_t macsize)
92 {
93 SSL3_RECORD *rec;
94 EVP_CIPHER_CTX *ds;
95 size_t l, i;
96 size_t bs;
97 const EVP_CIPHER *enc;
98 int provided;
99
100 rec = inrecs;
101 /*
102 * We shouldn't ever be called with more than one record in the SSLv3 case
103 */
104 if (n_recs != 1)
105 return 0;
106
107 ds = rl->enc_ctx;
108 if (ds == NULL || (enc = EVP_CIPHER_CTX_get0_cipher(ds)) == NULL)
109 return 0;
110
111 provided = (EVP_CIPHER_get0_provider(enc) != NULL);
112
113 l = rec->length;
114 bs = EVP_CIPHER_CTX_get_block_size(ds);
115
116 /* COMPRESS */
117
118 if ((bs != 1) && sending && !provided) {
119 /*
120 * We only do this for legacy ciphers. Provided ciphers add the
121 * padding on the provider side.
122 */
123 i = bs - (l % bs);
124
125 /* we need to add 'i-1' padding bytes */
126 l += i;
127 /*
128 * the last of these zero bytes will be overwritten with the
129 * padding length.
130 */
131 memset(&rec->input[rec->length], 0, i);
132 rec->length += i;
133 rec->input[l - 1] = (unsigned char)(i - 1);
134 }
135
136 if (!sending) {
137 if (l == 0 || l % bs != 0) {
138 /* Publicly invalid */
139 return 0;
140 }
141 /* otherwise, rec->length >= bs */
142 }
143
144 if (provided) {
145 int outlen;
146
147 if (!EVP_CipherUpdate(ds, rec->data, &outlen, rec->input,
148 (unsigned int)l))
149 return 0;
150 rec->length = outlen;
151
152 if (!sending && mac != NULL) {
153 /* Now get a pointer to the MAC */
154 OSSL_PARAM params[2], *p = params;
155
156 /* Get the MAC */
157 mac->alloced = 0;
158
159 *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC,
160 (void **)&mac->mac,
161 macsize);
162 *p = OSSL_PARAM_construct_end();
163
164 if (!EVP_CIPHER_CTX_get_params(ds, params)) {
165 /* Shouldn't normally happen */
166 RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
167 return 0;
168 }
169 }
170 } else {
171 if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) {
172 /* Shouldn't happen */
173 RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, ERR_R_INTERNAL_ERROR);
174 return 0;
175 }
176
177 if (!sending)
178 return ssl3_cbc_remove_padding_and_mac(&rec->length,
179 rec->orig_len,
180 rec->data,
181 (mac != NULL) ? &mac->mac : NULL,
182 (mac != NULL) ? &mac->alloced : NULL,
183 bs,
184 macsize,
185 rl->libctx);
186 }
187
188 return 1;
189 }
190
191 static const unsigned char ssl3_pad_1[48] = {
192 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
193 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
194 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
195 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
196 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
197 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
198 };
199
200 static const unsigned char ssl3_pad_2[48] = {
201 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
202 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
203 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
204 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
205 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
206 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
207 };
208
209 static int ssl3_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
210 int sending)
211 {
212 unsigned char *mac_sec, *seq = rl->sequence;
213 const EVP_MD_CTX *hash;
214 unsigned char *p, rec_char;
215 size_t md_size;
216 size_t npad;
217 int t;
218
219 mac_sec = &(rl->mac_secret[0]);
220 hash = rl->md_ctx;
221
222 t = EVP_MD_CTX_get_size(hash);
223 if (t < 0)
224 return 0;
225 md_size = t;
226 npad = (48 / md_size) * md_size;
227
228 if (!sending
229 && EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE
230 && ssl3_cbc_record_digest_supported(hash)) {
231 #ifdef OPENSSL_NO_DEPRECATED_3_0
232 return 0;
233 #else
234 /*
235 * This is a CBC-encrypted record. We must avoid leaking any
236 * timing-side channel information about how many blocks of data we
237 * are hashing because that gives an attacker a timing-oracle.
238 */
239
240 /*-
241 * npad is, at most, 48 bytes and that's with MD5:
242 * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
243 *
244 * With SHA-1 (the largest hash speced for SSLv3) the hash size
245 * goes up 4, but npad goes down by 8, resulting in a smaller
246 * total size.
247 */
248 unsigned char header[75];
249 size_t j = 0;
250 memcpy(header + j, mac_sec, md_size);
251 j += md_size;
252 memcpy(header + j, ssl3_pad_1, npad);
253 j += npad;
254 memcpy(header + j, seq, 8);
255 j += 8;
256 header[j++] = rec->type;
257 header[j++] = (unsigned char)(rec->length >> 8);
258 header[j++] = (unsigned char)(rec->length & 0xff);
259
260 /* Final param == is SSLv3 */
261 if (ssl3_cbc_digest_record(EVP_MD_CTX_get0_md(hash),
262 md, &md_size,
263 header, rec->input,
264 rec->length, rec->orig_len,
265 mac_sec, md_size, 1) <= 0)
266 return 0;
267 #endif
268 } else {
269 unsigned int md_size_u;
270 /* Chop the digest off the end :-) */
271 EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
272
273 if (md_ctx == NULL)
274 return 0;
275
276 rec_char = rec->type;
277 p = md;
278 s2n(rec->length, p);
279 if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
280 || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
281 || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0
282 || EVP_DigestUpdate(md_ctx, seq, 8) <= 0
283 || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0
284 || EVP_DigestUpdate(md_ctx, md, 2) <= 0
285 || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0
286 || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0
287 || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
288 || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
289 || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
290 || EVP_DigestUpdate(md_ctx, md, md_size) <= 0
291 || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
292 EVP_MD_CTX_free(md_ctx);
293 return 0;
294 }
295
296 EVP_MD_CTX_free(md_ctx);
297 }
298
299 ssl3_record_sequence_update(seq);
300 return 1;
301 }
302
303 struct record_functions_st ssl_3_0_funcs = {
304 ssl3_set_crypto_state,
305 ssl3_cipher,
306 ssl3_mac,
307 tls_default_set_protocol_version,
308 tls_default_read_n,
309 tls_get_more_records,
310 tls_default_validate_record_header,
311 tls_default_post_process_record,
312 tls_get_max_records_default,
313 tls_write_records_default
314 };