7#include <botan/nist_keywrap.h>
9#include <botan/block_cipher.h>
10#include <botan/exceptn.h>
11#include <botan/internal/int_utils.h>
12#include <botan/internal/loadstor.h>
18std::vector<uint8_t> raw_nist_key_wrap(
const uint8_t input[],
size_t input_len,
const BlockCipher& bc, uint64_t ICV) {
19 const size_t n = input_len / 8 + (input_len % 8 != 0 ? 1 : 0);
28 for(
size_t j = 0; j <= 5; ++j) {
29 for(
size_t i = 1; i <= n; ++i) {
30 const uint32_t t =
static_cast<uint32_t
>((n * j) + i);
37 uint8_t t_buf[4] = {0};
45 return std::vector<uint8_t>(R.begin(), R.end());
52 if(input_len < 16 || input_len % 8 != 0) {
56 const size_t n = (input_len - 8) / 8;
61 for(
size_t i = 0; i != 8; ++i) {
65 copy_mem(R.data(), input + 8, input_len - 8);
67 for(
size_t j = 0; j <= 5; ++j) {
68 for(
size_t i = n; i != 0; --i) {
69 const uint32_t t =
static_cast<uint32_t
>((5 - j) * n + i);
71 uint8_t t_buf[4] = {0};
96 if(input_len == 0 || input_len % 8 != 0) {
100 const uint64_t ICV = 0xA6A6A6A6A6A6A6A6;
107 std::vector<uint8_t> block(16);
109 copy_mem(block.data() + 8, input, input_len);
113 return raw_nist_key_wrap(input, input_len, bc, ICV);
119 throw Invalid_Argument(
"NIST key wrap algorithm requires a 128-bit cipher");
122 if(input_len < 16 || input_len % 8 != 0) {
126 const uint64_t ICV = 0xA6A6A6A6A6A6A6A6;
128 uint64_t ICV_out = 0;
131 if(input_len == 16) {
137 copy_mem(R.data(), block.data() + 8, 8);
139 R = raw_nist_key_unwrap(input, input_len, bc, ICV_out);
151 throw Invalid_Argument(
"NIST key wrap algorithm requires a 128-bit cipher");
158 const uint64_t ICV = 0xA65959A600000000 |
static_cast<uint32_t
>(input_len);
164 std::vector<uint8_t> block(16);
166 copy_mem(block.data() + 8, input, input_len);
170 return raw_nist_key_wrap(input, input_len, bc, ICV);
176 throw Invalid_Argument(
"NIST key wrap algorithm requires a 128-bit cipher");
179 if(input_len < 16 || input_len % 8 != 0) {
183 uint64_t ICV_out = 0;
186 if(input_len == 16) {
192 copy_mem(R.data(), block.data() + 8, 8);
194 R = raw_nist_key_unwrap(input, input_len, bc, ICV_out);
208 const uint64_t expected_ICV_max = 0xA65959A600000000 |
static_cast<uint32_t
>(R.size());
209 const uint64_t padding = expected_ICV_max - ICV_out;
217 const uint64_t padding_mask = (
static_cast<uint64_t
>(1) << (padding * 8)) - 1;
218 if((last_block & padding_mask) != 0) {
222 R.resize(R.size() -
static_cast<size_t>(padding));
void encrypt(const uint8_t in[], uint8_t out[]) const
void decrypt(const uint8_t in[], uint8_t out[]) const
virtual size_t block_size() const =0
std::vector< uint8_t > nist_key_wrap(const uint8_t input[], size_t input_len, const BlockCipher &bc)
constexpr T mul_or_throw(T a, T b, std::string_view msg)
constexpr void copy_mem(T *out, const T *in, size_t n)
std::vector< uint8_t > nist_key_wrap_padded(const uint8_t input[], size_t input_len, const BlockCipher &bc)
secure_vector< uint8_t > nist_key_unwrap_padded(const uint8_t input[], size_t input_len, const BlockCipher &bc)
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
std::vector< T, secure_allocator< T > > secure_vector
constexpr auto store_be(ParamTs &&... params)
constexpr auto load_be(ParamTs &&... params)
secure_vector< uint8_t > nist_key_unwrap(const uint8_t input[], size_t input_len, const BlockCipher &bc)