8#include <botan/internal/oaep.h>
10#include <botan/exceptn.h>
12#include <botan/internal/ct_utils.h>
13#include <botan/internal/mgf1.h>
20secure_vector<uint8_t> OAEP::pad(
const uint8_t in[],
23 RandomNumberGenerator& rng)
const {
27 throw Invalid_Argument(
"OAEP: Input is too large");
30 secure_vector<uint8_t> out(key_length);
32 rng.randomize(out.data(), m_Phash.size());
34 buffer_insert(out, m_Phash.size(), m_Phash.data(), m_Phash.size());
35 out[out.size() - in_length - 1] = 0x01;
38 mgf1_mask(*m_mgf1_hash, out.data(), m_Phash.size(), &out[m_Phash.size()], out.size() - m_Phash.size());
40 mgf1_mask(*m_mgf1_hash, &out[m_Phash.size()], out.size() - m_Phash.size(), out.data(), m_Phash.size());
48secure_vector<uint8_t> OAEP::unpad(uint8_t& valid_mask,
const uint8_t in[],
size_t in_length)
const {
71 secure_vector<uint8_t> input(in + 1, in + in_length);
73 const size_t hlen = m_Phash.size();
75 mgf1_mask(*m_mgf1_hash, &input[hlen], input.size() - hlen, input.data(), hlen);
77 mgf1_mask(*m_mgf1_hash, input.data(), hlen, &input[hlen], input.size() - hlen);
79 auto unpadded =
oaep_find_delim(valid_mask, input.data(), input.size(), m_Phash);
80 valid_mask &= leading_0.unpoisoned_value();
85 const uint8_t input[],
88 const size_t hlen = Phash.size();
91 if(input_len < 1 + 2 * hlen) {
97 size_t delim_idx = 2 * hlen;
101 for(
size_t i = delim_idx; i < input_len; ++i) {
105 const auto add_m = waiting_for_delim & zero_m;
107 bad_input_m |= waiting_for_delim & ~(zero_m | one_m);
111 waiting_for_delim &= zero_m;
115 bad_input_m |= waiting_for_delim;
120 valid_mask = (~bad_input_m).unpoisoned_value();
121 auto output =
CT::copy_output(bad_input_m, input, input_len, delim_idx);
132 if(keybits / 8 > 2 * m_Phash.size() + 1) {
133 return ((keybits / 8) - 2 * m_Phash.size() - 1);
139OAEP::OAEP(std::unique_ptr<HashFunction> hash, std::string_view P) : m_mgf1_hash(
std::move(hash)) {
140 m_Phash = m_mgf1_hash->process(P);
143OAEP::OAEP(std::unique_ptr<HashFunction> hash, std::unique_ptr<HashFunction> mgf1_hash, std::string_view P) :
144 m_mgf1_hash(
std::move(mgf1_hash)) {
145 auto phash = std::move(hash);
146 m_Phash = phash->process(P);
static Mask< T > is_equal(T x, T y)
static Mask< T > is_zero(T x)
T if_set_return(T x) const
static Mask< T > cleared()
OAEP(std::unique_ptr< HashFunction > hash, std::string_view P="")
size_t maximum_input_size(size_t) const override
void poison(const T *p, size_t n)
secure_vector< uint8_t > copy_output(CT::Mask< uint8_t > bad_input_u8, const uint8_t input[], size_t input_length, size_t offset)
void unpoison(const T *p, size_t n)
void mgf1_mask(HashFunction &hash, const uint8_t in[], size_t in_len, uint8_t out[], size_t out_len)
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
secure_vector< uint8_t > oaep_find_delim(uint8_t &valid_mask, const uint8_t input[], size_t input_len, const secure_vector< uint8_t > &Phash)
uint8_t ct_compare_u8(const uint8_t x[], const uint8_t y[], size_t len)
std::vector< T, secure_allocator< T > > secure_vector