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 "cipher_locl.h"
14 * Fills a single block of buffered data from the input, and returns the amount
15 * of data remaining in the input that is a multiple of the blocksize. The buffer
16 * is only filled if it already has some data in it, isn't full already or we
17 * don't have at least one block in the input.
19 * buf: a buffer of blocksize bytes
20 * buflen: contains the amount of data already in buf on entry. Updated with the
21 * amount of data in buf at the end. On entry *buflen must always be
22 * less than the blocksize
23 * blocksize: size of a block. Must be greater than 0 and a power of 2
24 * in: pointer to a pointer containing the input data
25 * inlen: amount of input data available
27 * On return buf is filled with as much data as possible up to a full block,
28 * *buflen is updated containing the amount of data in buf. *in is updated to
29 * the new location where input data should be read from, *inlen is updated with
30 * the remaining amount of data in *in. Returns the largest value <= *inlen
31 * which is a multiple of the blocksize.
33 size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
34 const unsigned char **in, size_t *inlen)
36 size_t blockmask = ~(blocksize - 1);
38 assert(*buflen <= blocksize);
39 assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0);
41 if (*buflen != blocksize && (*buflen != 0 || *inlen < blocksize)) {
42 size_t bufremain = blocksize - *buflen;
44 if (*inlen < bufremain)
46 memcpy(buf + *buflen, *in, bufremain);
52 return *inlen & blockmask;
56 * Fills the buffer with trailing data from an encryption/decryption that didn't
57 * fit into a full block.
59 int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
60 const unsigned char **in, size_t *inlen)
65 if (*buflen + *inlen > blocksize) {
66 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
70 memcpy(buf + *buflen, *in, *inlen);
77 /* Pad the final block for encryption */
78 void padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
81 unsigned char pad = (unsigned char)(blocksize - *buflen);
83 for (i = *buflen; i < blocksize; i++)
87 int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
92 if(len != blocksize) {
93 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
98 * The following assumes that the ciphertext has been authenticated.
99 * Otherwise it provides a padding oracle.
101 pad = buf[blocksize - 1];
102 if (pad == 0 || pad > blocksize) {
103 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);
106 for (i = 0; i < pad; i++) {
107 if (buf[--len] != pad) {
108 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);