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;
   }