Update copyright year
[openssl.git] / providers / implementations / ciphers / ciphercommon_block.c
index ac792d68d7a3acd331014197de5200ae4071b1ec..14f7503b3627a5c3ce4aa293cda2e121ab3142b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -8,8 +8,30 @@
  */
 
 #include <assert.h>
+/* For SSL3_VERSION, TLS1_VERSION etc */
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+#include <openssl/proverr.h>
+#include "internal/constant_time.h"
 #include "ciphercommon_local.h"
-#include "prov/providercommonerr.h"
+
+/* Functions defined in ssl/tls_pad.c */
+int ssl3_cbc_remove_padding_and_mac(size_t *reclen,
+                                    size_t origreclen,
+                                    unsigned char *recdata,
+                                    unsigned char **mac,
+                                    int *alloced,
+                                    size_t block_size, size_t mac_size,
+                                    OSSL_LIB_CTX *libctx);
+
+int tls1_cbc_remove_padding_and_mac(size_t *reclen,
+                                    size_t origreclen,
+                                    unsigned char *recdata,
+                                    unsigned char **mac,
+                                    int *alloced,
+                                    size_t block_size, size_t mac_size,
+                                    int aead,
+                                    OSSL_LIB_CTX *libctx);
 
 /*
  * Fills a single block of buffered data from the input, and returns the amount
@@ -31,8 +53,9 @@
  * the remaining amount of data in *in. Returns the largest value <= *inlen
  * which is a multiple of the blocksize.
  */
-size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
-                 const unsigned char **in, size_t *inlen)
+size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen,
+                             size_t blocksize,
+                             const unsigned char **in, size_t *inlen)
 {
     size_t blockmask = ~(blocksize - 1);
     size_t bufremain = blocksize - *buflen;
@@ -54,8 +77,8 @@ size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
  * Fills the buffer with trailing data from an encryption/decryption that didn't
  * fit into a full block.
  */
-int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
-                 const unsigned char **in, size_t *inlen)
+int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
+                             const unsigned char **in, size_t *inlen)
 {
     if (*inlen == 0)
         return 1;
@@ -73,7 +96,7 @@ int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
 }
 
 /* Pad the final block for encryption */
-void padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
+void ossl_cipher_padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
 {
     size_t i;
     unsigned char pad = (unsigned char)(blocksize - *buflen);
@@ -82,7 +105,7 @@ void padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
         buf[i] = pad;
 }
 
-int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
+int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
 {
     size_t pad, i;
     size_t len = *buflen;
@@ -110,3 +133,58 @@ int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
     *buflen = len;
     return 1;
 }
+
+/*-
+ * ossl_cipher_tlsunpadblock removes the CBC padding from the decrypted, TLS, CBC
+ * record in constant time. Also removes the MAC from the record in constant
+ * time.
+ *
+ * libctx: Our library context
+ * tlsversion: The TLS version in use, e.g. SSL3_VERSION, TLS1_VERSION, etc
+ * buf: The decrypted TLS record data
+ * buflen: The length of the decrypted TLS record data. Updated with the new
+ *         length after the padding is removed
+ * block_size: the block size of the cipher used to encrypt the record.
+ * mac: Location to store the pointer to the MAC
+ * alloced: Whether the MAC is stored in a newly allocated buffer, or whether
+ *          *mac points into *buf
+ * macsize: the size of the MAC inside the record (or 0 if there isn't one)
+ * aead: whether this is an aead cipher
+ * returns:
+ *   0: (in non-constant time) if the record is publicly invalid.
+ *   1: (in constant time) Record is publicly valid. If padding is invalid then
+ *      the mac is random
+ */
+int ossl_cipher_tlsunpadblock(OSSL_LIB_CTX *libctx, unsigned int tlsversion,
+                              unsigned char *buf, size_t *buflen,
+                              size_t blocksize,
+                              unsigned char **mac, int *alloced, size_t macsize,
+                              int aead)
+{
+    int ret;
+
+    switch (tlsversion) {
+    case SSL3_VERSION:
+        return ssl3_cbc_remove_padding_and_mac(buflen, *buflen, buf, mac,
+                                               alloced, blocksize, macsize,
+                                               libctx);
+
+    case TLS1_2_VERSION:
+    case DTLS1_2_VERSION:
+    case TLS1_1_VERSION:
+    case DTLS1_VERSION:
+    case DTLS1_BAD_VER:
+        /* Remove the explicit IV */
+        buf += blocksize;
+        *buflen -= blocksize;
+        /* Fall through */
+    case TLS1_VERSION:
+        ret = tls1_cbc_remove_padding_and_mac(buflen, *buflen, buf, mac,
+                                              alloced, blocksize, macsize,
+                                              aead, libctx);
+        return ret;
+
+    default:
+        return 0;
+    }
+}