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