Botan 3.2.0
Crypto and TLS for C&
eme_pkcs.cpp
Go to the documentation of this file.
1/*
2* PKCS #1 v1.5 Type 2 (encryption) padding
3* (C) 1999-2007,2015,2016 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/eme_pkcs.h>
9
10#include <botan/exceptn.h>
11#include <botan/rng.h>
12#include <botan/internal/ct_utils.h>
13
14namespace Botan {
15
16/*
17* PKCS1 Pad Operation
18*/
20 size_t inlen,
21 size_t key_length,
22 RandomNumberGenerator& rng) const {
23 key_length /= 8;
24
25 if(inlen > maximum_input_size(key_length * 8)) {
26 throw Invalid_Argument("PKCS1: Input is too large");
27 }
28
29 secure_vector<uint8_t> out(key_length);
30
31 out[0] = 0x02;
32 rng.randomize(out.data() + 1, (key_length - inlen - 2));
33
34 for(size_t j = 1; j != key_length - inlen - 1; ++j) {
35 if(out[j] == 0) {
36 out[j] = rng.next_nonzero_byte();
37 }
38 }
39
40 buffer_insert(out, key_length - inlen, in, inlen);
41
42 return out;
43}
44
45/*
46* PKCS1 Unpad Operation
47*/
48secure_vector<uint8_t> EME_PKCS1v15::unpad(uint8_t& valid_mask, const uint8_t in[], size_t inlen) const {
49 /*
50 * RSA decryption pads the ciphertext up to the modulus size, so this only
51 * occurs with very (!) small keys, or when fuzzing.
52 *
53 * 11 bytes == 00,02 + 8 bytes mandatory padding + 00
54 */
55 if(inlen < 11) {
56 valid_mask = false;
58 }
59
60 CT::poison(in, inlen);
61
64 size_t delim_idx = 2; // initial 0002
65
66 bad_input_m |= ~CT::Mask<uint8_t>::is_equal(in[0], 0);
67 bad_input_m |= ~CT::Mask<uint8_t>::is_equal(in[1], 2);
68
69 for(size_t i = 2; i < inlen; ++i) {
70 const auto is_zero_m = CT::Mask<uint8_t>::is_zero(in[i]);
71 delim_idx += seen_zero_m.if_not_set_return(1);
72 seen_zero_m |= is_zero_m;
73 }
74
75 // no zero delim -> bad padding
76 bad_input_m |= ~seen_zero_m;
77 /*
78 delim indicates < 8 bytes padding -> bad padding
79
80 We require 11 here because we are counting also the 00 delim byte
81 */
82 bad_input_m |= CT::Mask<uint8_t>(CT::Mask<size_t>::is_lt(delim_idx, 11));
83
84 valid_mask = (~bad_input_m).unpoisoned_value();
85 auto output = CT::copy_output(bad_input_m, in, inlen, delim_idx);
86
87 CT::unpoison(in, inlen);
88
89 return output;
90}
91
92/*
93* Return the max input size for a given key size
94*/
95size_t EME_PKCS1v15::maximum_input_size(size_t keybits) const {
96 if(keybits / 8 > 10) {
97 return ((keybits / 8) - 10);
98 } else {
99 return 0;
100 }
101}
102
103} // namespace Botan
static Mask< T > is_zero(T x)
Definition ct_utils.h:121
T if_not_set_return(T x) const
Definition ct_utils.h:221
static Mask< T > cleared()
Definition ct_utils.h:102
secure_vector< uint8_t > pad(const uint8_t[], size_t, size_t, RandomNumberGenerator &) const override
Definition eme_pkcs.cpp:19
size_t maximum_input_size(size_t) const override
Definition eme_pkcs.cpp:95
secure_vector< uint8_t > unpad(uint8_t &valid_mask, const uint8_t in[], size_t in_len) const override
Definition eme_pkcs.cpp:48
void randomize(std::span< uint8_t > output)
Definition rng.h:52
uint8_t next_nonzero_byte()
Definition rng.h:229
void poison(const T *p, size_t n)
Definition ct_utils.h:46
secure_vector< uint8_t > copy_output(CT::Mask< uint8_t > bad_input_u8, const uint8_t input[], size_t input_length, size_t offset)
Definition ct_utils.cpp:11
void unpoison(const T *p, size_t n)
Definition ct_utils.h:55
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition mem_ops.h:212
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61