Add build file support for generic symbol exports with DSOs
[openssl.git] / ssl / record / ssl3_record_tls13.c
index f1e1667b9df37355dc83956466121544216e0f54..a11ed483e6682b559bdd35f429eed532f29ca9bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
 {
     EVP_CIPHER_CTX *ctx;
-    unsigned char iv[EVP_MAX_IV_LENGTH];
-    size_t ivlen, taglen, offset, loop;
+    unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH];
+    size_t ivlen, taglen, offset, loop, hdrlen;
     unsigned char *staticiv;
     unsigned char *seq;
     int lenu, lenf;
     SSL3_RECORD *rec = &recs[0];
     uint32_t alg_enc;
+    WPACKET wpkt;
 
     if (n_recs != 1) {
         /* Should not happen */
@@ -51,7 +52,13 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
         seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
     }
 
-    if (ctx == NULL) {
+    /*
+     * If we're sending an alert and ctx != NULL then we must be forcing
+     * plaintext alerts. If we're reading and ctx != NULL then we allow
+     * plaintext alerts at certain points in the handshake. If we've got this
+     * far then we have already validated that a plaintext alert is ok here.
+     */
+    if (ctx == NULL || rec->type == SSL3_RT_ALERT) {
         memmove(rec->data, rec->input, rec->length);
         rec->input = rec->data;
         return 1;
@@ -143,7 +150,31 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
     if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0
             || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
                                              taglen,
-                                             rec->data + rec->length) <= 0)
+                                             rec->data + rec->length) <= 0)) {
+        return -1;
+    }
+
+    /* Set up the AAD */
+    if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
+            || !WPACKET_put_bytes_u8(&wpkt, rec->type)
+            || !WPACKET_put_bytes_u16(&wpkt, rec->rec_version)
+            || !WPACKET_put_bytes_u16(&wpkt, rec->length + taglen)
+            || !WPACKET_get_total_written(&wpkt, &hdrlen)
+            || hdrlen != SSL3_RT_HEADER_LENGTH
+            || !WPACKET_finish(&wpkt)) {
+        WPACKET_cleanup(&wpkt);
+        return -1;
+    }
+
+    /*
+     * For CCM we must explicitly set the total plaintext length before we add
+     * any AAD.
+     */
+    if (((alg_enc & SSL_AESCCM) != 0
+                 && EVP_CipherUpdate(ctx, NULL, &lenu, NULL,
+                                     (unsigned int)rec->length) <= 0)
+            || EVP_CipherUpdate(ctx, NULL, &lenu, recheader,
+                                sizeof(recheader)) <= 0
             || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
                                 (unsigned int)rec->length) <= 0
             || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0