2 * Copyright 2019 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 #include <openssl/evp.h>
12 #include <openssl/err.h>
13 #include "ciphers_locl.h"
17 * Fills a single block of buffered data from the input, and returns the amount
18 * of data remaining in the input that is a multiple of the blocksize. The buffer
19 * is only filled if it already has some data in it, isn't full already or we
20 * don't have at least one block in the input.
22 * buf: a buffer of blocksize bytes
23 * buflen: contains the amount of data already in buf on entry. Updated with the
24 * amount of data in buf at the end. On entry *buflen must always be
25 * less than the blocksize
26 * blocksize: size of a block. Must be greater than 0 and a power of 2
27 * in: pointer to a pointer containing the input data
28 * inlen: amount of input data available
30 * On return buf is filled with as much data as possible up to a full block,
31 * *buflen is updated containing the amount of data in buf. *in is updated to
32 * the new location where input data should be read from, *inlen is updated with
33 * the remaining amount of data in *in. Returns the largest value <= *inlen
34 * which is a multiple of the blocksize.
36 size_t fillblock(unsigned char *buf
, size_t *buflen
, size_t blocksize
,
37 const unsigned char **in
, size_t *inlen
)
39 size_t blockmask
= ~(blocksize
- 1);
41 assert(*buflen
<= blocksize
);
42 assert(blocksize
> 0 && (blocksize
& (blocksize
- 1)) == 0);
44 if (*buflen
!= blocksize
&& (*buflen
!= 0 || *inlen
< blocksize
)) {
45 size_t bufremain
= blocksize
- *buflen
;
47 if (*inlen
< bufremain
)
49 memcpy(buf
+ *buflen
, *in
, bufremain
);
55 return *inlen
& blockmask
;
59 * Fills the buffer with trailing data from an encryption/decryption that didn't
60 * fit into a full block.
62 int trailingdata(unsigned char *buf
, size_t *buflen
, size_t blocksize
,
63 const unsigned char **in
, size_t *inlen
)
68 if (*buflen
+ *inlen
> blocksize
)
71 memcpy(buf
+ *buflen
, *in
, *inlen
);
78 /* Pad the final block for encryption */
79 void padblock(unsigned char *buf
, size_t *buflen
, size_t blocksize
)
82 unsigned char pad
= (unsigned char)(blocksize
- *buflen
);
84 for (i
= *buflen
; i
< blocksize
; i
++)
88 int unpadblock(unsigned char *buf
, size_t *buflen
, size_t blocksize
)
97 * The following assumes that the ciphertext has been authenticated.
98 * Otherwise it provides a padding oracle.
100 pad
= buf
[blocksize
- 1];
101 if (pad
== 0 || pad
> blocksize
) {
102 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX
, EVP_R_BAD_DECRYPT
);
105 for (i
= 0; i
< pad
; i
++) {
106 if (buf
[--len
] != pad
) {
107 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX
, EVP_R_BAD_DECRYPT
);