1 /* 2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <assert.h> 11 /* For SSL3_VERSION, TLS1_VERSION etc */ 12 #include <openssl/prov_ssl.h> 13 #include <openssl/rand.h> 14 #include <openssl/proverr.h> 15 #include "internal/constant_time.h" 16 #include "ciphercommon_local.h" 17 18 /* Functions defined in ssl/tls_pad.c */ 19 int ssl3_cbc_remove_padding_and_mac(size_t *reclen, 20 size_t origreclen, 21 unsigned char *recdata, 22 unsigned char **mac, 23 int *alloced, 24 size_t block_size, size_t mac_size, 25 OSSL_LIB_CTX *libctx); 26 27 int tls1_cbc_remove_padding_and_mac(size_t *reclen, 28 size_t origreclen, 29 unsigned char *recdata, 30 unsigned char **mac, 31 int *alloced, 32 size_t block_size, size_t mac_size, 33 int aead, 34 OSSL_LIB_CTX *libctx); 35 36 /* 37 * Fills a single block of buffered data from the input, and returns the amount 38 * of data remaining in the input that is a multiple of the blocksize. The buffer 39 * is only filled if it already has some data in it, isn't full already or we 40 * don't have at least one block in the input. 41 * 42 * buf: a buffer of blocksize bytes 43 * buflen: contains the amount of data already in buf on entry. Updated with the 44 * amount of data in buf at the end. On entry *buflen must always be 45 * less than the blocksize 46 * blocksize: size of a block. Must be greater than 0 and a power of 2 47 * in: pointer to a pointer containing the input data 48 * inlen: amount of input data available 49 * 50 * On return buf is filled with as much data as possible up to a full block, 51 * *buflen is updated containing the amount of data in buf. *in is updated to 52 * the new location where input data should be read from, *inlen is updated with 53 * the remaining amount of data in *in. Returns the largest value <= *inlen 54 * which is a multiple of the blocksize. 55 */ 56 size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen, 57 size_t blocksize, 58 const unsigned char **in, size_t *inlen) 59 { 60 size_t blockmask = ~(blocksize - 1); 61 size_t bufremain = blocksize - *buflen; 62 63 assert(*buflen <= blocksize); 64 assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0); 65 66 if (*inlen < bufremain) 67 bufremain = *inlen; 68 memcpy(buf + *buflen, *in, bufremain); 69 *in += bufremain; 70 *inlen -= bufremain; 71 *buflen += bufremain; 72 73 return *inlen & blockmask; 74 } 75 76 /* 77 * Fills the buffer with trailing data from an encryption/decryption that didn't 78 * fit into a full block. 79 */ 80 int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, 81 const unsigned char **in, size_t *inlen) 82 { 83 if (*inlen == 0) 84 return 1; 85 86 if (*buflen + *inlen > blocksize) { 87 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 88 return 0; 89 } 90 91 memcpy(buf + *buflen, *in, *inlen); 92 *buflen += *inlen; 93 *inlen = 0; 94 95 return 1; 96 } 97 98 /* Pad the final block for encryption */ 99 void ossl_cipher_padblock(unsigned char *buf, size_t *buflen, size_t blocksize) 100 { 101 size_t i; 102 unsigned char pad = (unsigned char)(blocksize - *buflen); 103 104 for (i = *buflen; i < blocksize; i++) 105 buf[i] = pad; 106 } 107 108 int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize) 109 { 110 size_t pad, i; 111 size_t len = *buflen; 112 113 if(len != blocksize) { 114 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 115 return 0; 116 } 117 118 /* 119 * The following assumes that the ciphertext has been authenticated. 120 * Otherwise it provides a padding oracle. 121 */ 122 pad = buf[blocksize - 1]; 123 if (pad == 0 || pad > blocksize) { 124 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); 125 return 0; 126 } 127 for (i = 0; i < pad; i++) { 128 if (buf[--len] != pad) { 129 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); 130 return 0; 131 } 132 } 133 *buflen = len; 134 return 1; 135 } 136 137 /*- 138 * ossl_cipher_tlsunpadblock removes the CBC padding from the decrypted, TLS, CBC 139 * record in constant time. Also removes the MAC from the record in constant 140 * time. 141 * 142 * libctx: Our library context 143 * tlsversion: The TLS version in use, e.g. SSL3_VERSION, TLS1_VERSION, etc 144 * buf: The decrypted TLS record data 145 * buflen: The length of the decrypted TLS record data. Updated with the new 146 * length after the padding is removed 147 * block_size: the block size of the cipher used to encrypt the record. 148 * mac: Location to store the pointer to the MAC 149 * alloced: Whether the MAC is stored in a newly allocated buffer, or whether 150 * *mac points into *buf 151 * macsize: the size of the MAC inside the record (or 0 if there isn't one) 152 * aead: whether this is an aead cipher 153 * returns: 154 * 0: (in non-constant time) if the record is publicly invalid. 155 * 1: (in constant time) Record is publicly valid. If padding is invalid then 156 * the mac is random 157 */ 158 int ossl_cipher_tlsunpadblock(OSSL_LIB_CTX *libctx, unsigned int tlsversion, 159 unsigned char *buf, size_t *buflen, 160 size_t blocksize, 161 unsigned char **mac, int *alloced, size_t macsize, 162 int aead) 163 { 164 int ret; 165 166 switch (tlsversion) { 167 case SSL3_VERSION: 168 return ssl3_cbc_remove_padding_and_mac(buflen, *buflen, buf, mac, 169 alloced, blocksize, macsize, 170 libctx); 171 172 case TLS1_2_VERSION: 173 case DTLS1_2_VERSION: 174 case TLS1_1_VERSION: 175 case DTLS1_VERSION: 176 case DTLS1_BAD_VER: 177 /* Remove the explicit IV */ 178 buf += blocksize; 179 *buflen -= blocksize; 180 /* Fall through */ 181 case TLS1_VERSION: 182 ret = tls1_cbc_remove_padding_and_mac(buflen, *buflen, buf, mac, 183 alloced, blocksize, macsize, 184 aead, libctx); 185 return ret; 186 187 default: 188 return 0; 189 } 190 } 191