]>
git.ipfire.org Git - thirdparty/openssl.git/blob - providers/implementations/ciphers/ciphercommon_block.c
2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 /* For SSL3_VERSION, TLS1_VERSION etc */
12 #include <openssl/ssl.h>
13 #include <openssl/rand.h>
14 #include "internal/constant_time.h"
15 #include "ciphercommon_local.h"
16 #include "prov/providercommonerr.h"
18 /* Functions defined in ssl/tls_pad.c */
19 int ssl3_cbc_remove_padding_and_mac(size_t *reclen
,
21 unsigned char *recdata
,
24 size_t block_size
, size_t mac_size
,
25 OSSL_LIB_CTX
*libctx
);
27 int tls1_cbc_remove_padding_and_mac(size_t *reclen
,
29 unsigned char *recdata
,
32 size_t block_size
, size_t mac_size
,
34 OSSL_LIB_CTX
*libctx
);
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.
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
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.
56 size_t fillblock(unsigned char *buf
, size_t *buflen
, size_t blocksize
,
57 const unsigned char **in
, size_t *inlen
)
59 size_t blockmask
= ~(blocksize
- 1);
60 size_t bufremain
= blocksize
- *buflen
;
62 assert(*buflen
<= blocksize
);
63 assert(blocksize
> 0 && (blocksize
& (blocksize
- 1)) == 0);
65 if (*inlen
< bufremain
)
67 memcpy(buf
+ *buflen
, *in
, bufremain
);
72 return *inlen
& blockmask
;
76 * Fills the buffer with trailing data from an encryption/decryption that didn't
77 * fit into a full block.
79 int trailingdata(unsigned char *buf
, size_t *buflen
, size_t blocksize
,
80 const unsigned char **in
, size_t *inlen
)
85 if (*buflen
+ *inlen
> blocksize
) {
86 ERR_raise(ERR_LIB_PROV
, ERR_R_INTERNAL_ERROR
);
90 memcpy(buf
+ *buflen
, *in
, *inlen
);
97 /* Pad the final block for encryption */
98 void padblock(unsigned char *buf
, size_t *buflen
, size_t blocksize
)
101 unsigned char pad
= (unsigned char)(blocksize
- *buflen
);
103 for (i
= *buflen
; i
< blocksize
; i
++)
107 int unpadblock(unsigned char *buf
, size_t *buflen
, size_t blocksize
)
110 size_t len
= *buflen
;
112 if(len
!= blocksize
) {
113 ERR_raise(ERR_LIB_PROV
, ERR_R_INTERNAL_ERROR
);
118 * The following assumes that the ciphertext has been authenticated.
119 * Otherwise it provides a padding oracle.
121 pad
= buf
[blocksize
- 1];
122 if (pad
== 0 || pad
> blocksize
) {
123 ERR_raise(ERR_LIB_PROV
, PROV_R_BAD_DECRYPT
);
126 for (i
= 0; i
< pad
; i
++) {
127 if (buf
[--len
] != pad
) {
128 ERR_raise(ERR_LIB_PROV
, PROV_R_BAD_DECRYPT
);
137 * tlsunpadblock removes the CBC padding from the decrypted, TLS, CBC
138 * record in constant time. Also removes the MAC from the record in constant
141 * libctx: Our library context
142 * tlsversion: The TLS version in use, e.g. SSL3_VERSION, TLS1_VERSION, etc
143 * buf: The decrypted TLS record data
144 * buflen: The length of the decrypted TLS record data. Updated with the new
145 * length after the padding is removed
146 * block_size: the block size of the cipher used to encrypt the record.
147 * mac: Location to store the pointer to the MAC
148 * alloced: Whether the MAC is stored in a newly allocated buffer, or whether
149 * *mac points into *buf
150 * macsize: the size of the MAC inside the record (or 0 if there isn't one)
151 * aead: whether this is an aead cipher
153 * 0: (in non-constant time) if the record is publicly invalid.
154 * 1: (in constant time) Record is publicly valid. If padding is invalid then
157 int tlsunpadblock(OSSL_LIB_CTX
*libctx
, unsigned int tlsversion
,
158 unsigned char *buf
, size_t *buflen
, size_t blocksize
,
159 unsigned char **mac
, int *alloced
, size_t macsize
, int aead
)
163 switch (tlsversion
) {
165 return ssl3_cbc_remove_padding_and_mac(buflen
, *buflen
, buf
, mac
,
166 alloced
, blocksize
, macsize
,
170 case DTLS1_2_VERSION
:
174 /* Remove the explicit IV */
176 *buflen
-= blocksize
;
179 ret
= tls1_cbc_remove_padding_and_mac(buflen
, *buflen
, buf
, mac
,
180 alloced
, blocksize
, macsize
,