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 */
ossl_cipher_fillblock(unsigned char * buf,size_t * buflen,size_t blocksize,const unsigned char ** in,size_t * inlen)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 */
ossl_cipher_trailingdata(unsigned char * buf,size_t * buflen,size_t blocksize,const unsigned char ** in,size_t * inlen)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 */
ossl_cipher_padblock(unsigned char * buf,size_t * buflen,size_t blocksize)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
ossl_cipher_unpadblock(unsigned char * buf,size_t * buflen,size_t blocksize)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 */
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)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