]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/common/ciphers/block.c
Reorganize private crypto header files
[thirdparty/openssl.git] / providers / common / ciphers / block.c
CommitLineData
aab26e6f
MC
1/*
2 * Copyright 2019 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
aab26e6f 10#include <assert.h>
e1178600 11#include "cipher_locl.h"
4a42e264 12#include "internal/providercommonerr.h"
aab26e6f
MC
13
14/*
15 * Fills a single block of buffered data from the input, and returns the amount
16 * of data remaining in the input that is a multiple of the blocksize. The buffer
17 * is only filled if it already has some data in it, isn't full already or we
18 * don't have at least one block in the input.
19 *
20 * buf: a buffer of blocksize bytes
21 * buflen: contains the amount of data already in buf on entry. Updated with the
22 * amount of data in buf at the end. On entry *buflen must always be
23 * less than the blocksize
24 * blocksize: size of a block. Must be greater than 0 and a power of 2
25 * in: pointer to a pointer containing the input data
26 * inlen: amount of input data available
27 *
28 * On return buf is filled with as much data as possible up to a full block,
29 * *buflen is updated containing the amount of data in buf. *in is updated to
30 * the new location where input data should be read from, *inlen is updated with
31 * the remaining amount of data in *in. Returns the largest value <= *inlen
32 * which is a multiple of the blocksize.
33 */
34size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
35 const unsigned char **in, size_t *inlen)
36{
37 size_t blockmask = ~(blocksize - 1);
38
39 assert(*buflen <= blocksize);
40 assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0);
41
42 if (*buflen != blocksize && (*buflen != 0 || *inlen < blocksize)) {
43 size_t bufremain = blocksize - *buflen;
44
45 if (*inlen < bufremain)
46 bufremain = *inlen;
47 memcpy(buf + *buflen, *in, bufremain);
48 *in += bufremain;
49 *inlen -= bufremain;
50 *buflen += bufremain;
51 }
52
53 return *inlen & blockmask;
54}
55
56/*
57 * Fills the buffer with trailing data from an encryption/decryption that didn't
58 * fit into a full block.
59 */
60int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
61 const unsigned char **in, size_t *inlen)
62{
63 if (*inlen == 0)
64 return 1;
65
6caf7f3a 66 if (*buflen + *inlen > blocksize) {
784883fc 67 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
aab26e6f 68 return 0;
6caf7f3a 69 }
aab26e6f
MC
70
71 memcpy(buf + *buflen, *in, *inlen);
72 *buflen += *inlen;
73 *inlen = 0;
74
75 return 1;
76}
77
78/* Pad the final block for encryption */
79void padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
80{
81 size_t i;
82 unsigned char pad = (unsigned char)(blocksize - *buflen);
83
84 for (i = *buflen; i < blocksize; i++)
85 buf[i] = pad;
86}
87
88int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
89{
90 size_t pad, i;
91 size_t len = *buflen;
92
6caf7f3a 93 if(len != blocksize) {
784883fc 94 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
aab26e6f 95 return 0;
6caf7f3a 96 }
aab26e6f
MC
97
98 /*
99 * The following assumes that the ciphertext has been authenticated.
100 * Otherwise it provides a padding oracle.
101 */
102 pad = buf[blocksize - 1];
103 if (pad == 0 || pad > blocksize) {
784883fc 104 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);
aab26e6f
MC
105 return 0;
106 }
107 for (i = 0; i < pad; i++) {
108 if (buf[--len] != pad) {
784883fc 109 ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);
aab26e6f
MC
110 return 0;
111 }
112 }
113 *buflen = len;
114 return 1;
115}