Botan 3.3.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/mem_ops.h>
12#include <botan/rng.h>
13#include <botan/internal/ct_utils.h>
14#include <botan/internal/stl_util.h>
15
16namespace Botan {
17
18/*
19* PKCS1 Pad Operation
20*/
22 size_t inlen,
23 size_t key_length,
24 RandomNumberGenerator& rng) const {
25 key_length /= 8;
26
27 if(inlen > maximum_input_size(key_length * 8)) {
28 throw Invalid_Argument("PKCS1: Input is too large");
29 }
30
31 secure_vector<uint8_t> out(key_length);
32 BufferStuffer stuffer(out);
33
34 const size_t padding_bytes = key_length - inlen - 2;
35
36 stuffer.append(0x02);
37 for(size_t i = 0; i != padding_bytes; ++i) {
38 stuffer.append(rng.next_nonzero_byte());
39 }
40 stuffer.append(0x00);
41 stuffer.append({in, inlen});
42 BOTAN_ASSERT_NOMSG(stuffer.full());
43
44 return out;
45}
46
47/*
48* PKCS1 Unpad Operation
49*/
50secure_vector<uint8_t> EME_PKCS1v15::unpad(uint8_t& valid_mask, const uint8_t in[], size_t inlen) const {
51 /*
52 * RSA decryption pads the ciphertext up to the modulus size, so this only
53 * occurs with very (!) small keys, or when fuzzing.
54 *
55 * 11 bytes == 00,02 + 8 bytes mandatory padding + 00
56 */
57 if(inlen < 11) {
58 valid_mask = false;
60 }
61
62 CT::poison(in, inlen);
63
66 size_t delim_idx = 2; // initial 0002
67
68 bad_input_m |= ~CT::Mask<uint8_t>::is_equal(in[0], 0);
69 bad_input_m |= ~CT::Mask<uint8_t>::is_equal(in[1], 2);
70
71 for(size_t i = 2; i < inlen; ++i) {
72 const auto is_zero_m = CT::Mask<uint8_t>::is_zero(in[i]);
73 delim_idx += seen_zero_m.if_not_set_return(1);
74 seen_zero_m |= is_zero_m;
75 }
76
77 // no zero delim -> bad padding
78 bad_input_m |= ~seen_zero_m;
79 /*
80 delim indicates < 8 bytes padding -> bad padding
81
82 We require 11 here because we are counting also the 00 delim byte
83 */
84 bad_input_m |= CT::Mask<uint8_t>(CT::Mask<size_t>::is_lt(delim_idx, 11));
85
86 valid_mask = (~bad_input_m).unpoisoned_value();
87 auto output = CT::copy_output(bad_input_m, in, inlen, delim_idx);
88
89 CT::unpoison(in, inlen);
90
91 return output;
92}
93
94/*
95* Return the max input size for a given key size
96*/
97size_t EME_PKCS1v15::maximum_input_size(size_t keybits) const {
98 if(keybits / 8 > 10) {
99 return ((keybits / 8) - 10);
100 } else {
101 return 0;
102 }
103}
104
105} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
Helper class to ease in-place marshalling of concatenated fixed-length values.
Definition stl_util.h:199
bool full() const
Definition stl_util.h:244
void append(std::span< const uint8_t > buffer)
Definition stl_util.h:234
static Mask< T > is_zero(T x)
Definition ct_utils.h:123
T if_not_set_return(T x) const
Definition ct_utils.h:223
static Mask< T > cleared()
Definition ct_utils.h:104
secure_vector< uint8_t > pad(const uint8_t[], size_t, size_t, RandomNumberGenerator &) const override
Definition eme_pkcs.cpp:21
size_t maximum_input_size(size_t) const override
Definition eme_pkcs.cpp:97
secure_vector< uint8_t > unpad(uint8_t &valid_mask, const uint8_t in[], size_t in_len) const override
Definition eme_pkcs.cpp:50
uint8_t next_nonzero_byte()
Definition rng.h:228
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
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61