Allow dtls_seal_record to work in-place.
This will let us avoid a scratch buffer when assembling DTLS handshake
packets in the write_message-less flow.
BUG=72
Change-Id: I15e78efe3a9e3933c307e599f0043427330f4a9e
Reviewed-on: https://boringssl-review.googlesource.com/13262
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/dtls_record.c b/ssl/dtls_record.c
index e507f5c..35c08b0 100644
--- a/ssl/dtls_record.c
+++ b/ssl/dtls_record.c
@@ -249,10 +249,24 @@
return ssl_open_record_success;
}
+size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch) {
+ const SSL_AEAD_CTX *aead = ssl->s3->aead_write_ctx;
+ if (use_epoch == dtls1_use_previous_epoch) {
+ /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
+ * (negotiated cipher) exist. */
+ assert(ssl->d1->w_epoch == 1);
+ aead = NULL;
+ }
+
+ return DTLS1_RT_HEADER_LENGTH + SSL_AEAD_CTX_explicit_nonce_len(aead);
+}
+
int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
uint8_t type, const uint8_t *in, size_t in_len,
enum dtls1_use_epoch_t use_epoch) {
- if (buffers_alias(in, in_len, out, max_out)) {
+ const size_t prefix = dtls_seal_prefix_len(ssl, use_epoch);
+ if (buffers_alias(in, in_len, out, max_out) &&
+ (max_out < prefix || out + prefix != in)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
return 0;
}