/*
- * 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
*/
#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
* 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;
* 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;
}
/* 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);
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;
*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;
+ }
+}