diff options
author | jsing <> | 2020-08-09 16:02:58 +0000 |
---|---|---|
committer | jsing <> | 2020-08-09 16:02:58 +0000 |
commit | b3dbcda2404dbe31481fae8d6817cbc0a3362031 (patch) | |
tree | 1bce0663b79d08c1bf38e62b09a464cbcc5bd6ce /src/lib/libssl/d1_pkt.c | |
parent | e770512d626b103f809dfdecb1ba758a92b5f57b (diff) | |
download | openbsd-b3dbcda2404dbe31481fae8d6817cbc0a3362031.tar.gz openbsd-b3dbcda2404dbe31481fae8d6817cbc0a3362031.tar.bz2 openbsd-b3dbcda2404dbe31481fae8d6817cbc0a3362031.zip |
Use CBB more correctly when writing SSL3/DTLS records.
Previously we used CBB to build the record headers, but not the entire
record. Use CBB_init_fixed() upfront, then build the record header and
add space for the record content. However, in order to do this we need
to determine the length of the record upfront.
This simplifies the code, removes a number of manual bounds checks and
makes way for further improvements.
ok inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/d1_pkt.c')
-rw-r--r-- | src/lib/libssl/d1_pkt.c | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 5bbdf5f738..dd7d9aa76c 100644 --- a/src/lib/libssl/d1_pkt.c +++ b/src/lib/libssl/d1_pkt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_pkt.c,v 1.77 2020/08/09 15:46:28 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.78 2020/08/09 16:02:58 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
@@ -1177,10 +1177,12 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1177 | SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); | 1177 | SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); |
1178 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); | 1178 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); |
1179 | SSL_SESSION *sess = s->session; | 1179 | SSL_SESSION *sess = s->session; |
1180 | int eivlen = 0, mac_size = 0; | 1180 | int block_size = 0, eivlen = 0, mac_size = 0; |
1181 | unsigned char *p; | 1181 | size_t pad_len, record_len; |
1182 | CBB cbb, fragment; | ||
1183 | size_t out_len; | ||
1184 | uint8_t *p; | ||
1182 | int ret; | 1185 | int ret; |
1183 | CBB cbb; | ||
1184 | 1186 | ||
1185 | memset(&cbb, 0, sizeof(cbb)); | 1187 | memset(&cbb, 0, sizeof(cbb)); |
1186 | 1188 | ||
@@ -1209,12 +1211,38 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1209 | goto err; | 1211 | goto err; |
1210 | } | 1212 | } |
1211 | 1213 | ||
1214 | /* Explicit IV length. */ | ||
1215 | if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { | ||
1216 | int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx); | ||
1217 | if (mode == EVP_CIPH_CBC_MODE) { | ||
1218 | eivlen = EVP_CIPHER_CTX_iv_length(s->internal->enc_write_ctx); | ||
1219 | if (eivlen <= 1) | ||
1220 | eivlen = 0; | ||
1221 | } | ||
1222 | } else if (s->internal->aead_write_ctx != NULL && | ||
1223 | s->internal->aead_write_ctx->variable_nonce_in_record) { | ||
1224 | eivlen = s->internal->aead_write_ctx->variable_nonce_len; | ||
1225 | } | ||
1226 | |||
1227 | /* Determine length of record fragment. */ | ||
1228 | record_len = eivlen + len + mac_size; | ||
1229 | if (s->internal->enc_write_ctx != NULL) { | ||
1230 | block_size = EVP_CIPHER_CTX_block_size(s->internal->enc_write_ctx); | ||
1231 | if (block_size <= 0 || block_size > EVP_MAX_BLOCK_LENGTH) | ||
1232 | goto err; | ||
1233 | if (block_size > 1) { | ||
1234 | pad_len = block_size - (record_len % block_size); | ||
1235 | record_len += pad_len; | ||
1236 | } | ||
1237 | } else if (s->internal->aead_write_ctx != NULL) { | ||
1238 | record_len += s->internal->aead_write_ctx->tag_len; | ||
1239 | } | ||
1240 | |||
1212 | /* DTLS implements explicit IV, so no need for empty fragments. */ | 1241 | /* DTLS implements explicit IV, so no need for empty fragments. */ |
1213 | 1242 | ||
1214 | p = wb->buf; | ||
1215 | wb->offset = 0; | 1243 | wb->offset = 0; |
1216 | 1244 | ||
1217 | if (!CBB_init_fixed(&cbb, p, DTLS1_RT_HEADER_LENGTH)) | 1245 | if (!CBB_init_fixed(&cbb, wb->buf, wb->len)) |
1218 | goto err; | 1246 | goto err; |
1219 | 1247 | ||
1220 | /* Write the header. */ | 1248 | /* Write the header. */ |
@@ -1226,21 +1254,10 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1226 | goto err; | 1254 | goto err; |
1227 | if (!CBB_add_bytes(&cbb, &(S3I(s)->write_sequence[2]), 6)) | 1255 | if (!CBB_add_bytes(&cbb, &(S3I(s)->write_sequence[2]), 6)) |
1228 | goto err; | 1256 | goto err; |
1229 | 1257 | if (!CBB_add_u16_length_prefixed(&cbb, &fragment)) | |
1230 | p += DTLS1_RT_HEADER_LENGTH; | 1258 | goto err; |
1231 | 1259 | if (!CBB_add_space(&fragment, &p, record_len)) | |
1232 | /* Explicit IV length. */ | 1260 | goto err; |
1233 | if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { | ||
1234 | int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx); | ||
1235 | if (mode == EVP_CIPH_CBC_MODE) { | ||
1236 | eivlen = EVP_CIPHER_CTX_iv_length(s->internal->enc_write_ctx); | ||
1237 | if (eivlen <= 1) | ||
1238 | eivlen = 0; | ||
1239 | } | ||
1240 | } else if (s->internal->aead_write_ctx != NULL && | ||
1241 | s->internal->aead_write_ctx->variable_nonce_in_record) { | ||
1242 | eivlen = s->internal->aead_write_ctx->variable_nonce_len; | ||
1243 | } | ||
1244 | 1261 | ||
1245 | wr->type = type; | 1262 | wr->type = type; |
1246 | wr->data = p + eivlen; | 1263 | wr->data = p + eivlen; |
@@ -1262,11 +1279,14 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1262 | if (tls1_enc(s, 1) != 1) | 1279 | if (tls1_enc(s, 1) != 1) |
1263 | goto err; | 1280 | goto err; |
1264 | 1281 | ||
1265 | if (!CBB_add_u16(&cbb, wr->length)) | 1282 | if (wr->length != record_len) |
1266 | goto err; | 1283 | goto err; |
1267 | if (!CBB_finish(&cbb, NULL, NULL)) | 1284 | |
1285 | if (!CBB_finish(&cbb, NULL, &out_len)) | ||
1268 | goto err; | 1286 | goto err; |
1269 | 1287 | ||
1288 | wb->left = out_len; | ||
1289 | |||
1270 | /* | 1290 | /* |
1271 | * We should now have wr->data pointing to the encrypted data, | 1291 | * We should now have wr->data pointing to the encrypted data, |
1272 | * which is wr->length long. | 1292 | * which is wr->length long. |
@@ -1276,8 +1296,6 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1276 | 1296 | ||
1277 | tls1_record_sequence_increment(S3I(s)->write_sequence); | 1297 | tls1_record_sequence_increment(S3I(s)->write_sequence); |
1278 | 1298 | ||
1279 | wb->left = wr->length; | ||
1280 | |||
1281 | /* | 1299 | /* |
1282 | * Memorize arguments so that ssl3_write_pending can detect | 1300 | * Memorize arguments so that ssl3_write_pending can detect |
1283 | * bad write retries later. | 1301 | * bad write retries later. |