Coverage Report

Created: 2023-02-13 06:21

/src/botan/src/lib/stream/shake_cipher/shake_cipher.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SHAKE-128 and SHAKE-256
3
 * (C) 2016 Jack Lloyd
4
 *     2022 René Meusel, Michael Boric - Rohde & Schwarz Cybersecurity
5
 *
6
 * Botan is released under the Simplified BSD License (see license.txt)
7
 */
8
9
#include <botan/internal/shake_cipher.h>
10
#include <botan/exceptn.h>
11
#include <botan/internal/sha3.h>
12
#include <botan/internal/loadstor.h>
13
14
namespace Botan {
15
16
SHAKE_Cipher::SHAKE_Cipher(size_t shake_rate) :
17
   m_shake_rate(shake_rate),
18
   m_buf_pos(0)
19
0
   {
20
0
   BOTAN_ASSERT_NOMSG(shake_rate >= 72 && shake_rate <= 168);
21
0
   }
22
23
void SHAKE_Cipher::clear()
24
0
   {
25
0
   zap(m_state);
26
0
   zap(m_buffer);
27
0
   m_buf_pos = 0;
28
0
   }
29
30
void SHAKE_Cipher::set_iv(const uint8_t /*iv*/[], size_t length)
31
0
   {
32
   /*
33
   * This could be supported in some way (say, by treating iv as
34
   * a prefix or suffix of the key).
35
   */
36
0
   if(length != 0)
37
0
      { throw Invalid_IV_Length(name(), length); }
38
0
   }
39
40
void SHAKE_Cipher::seek(uint64_t /*offset*/)
41
0
   {
42
0
   throw Not_Implemented("SHAKE_Cipher::seek");
43
0
   }
44
45
void SHAKE_Cipher::cipher(const uint8_t in[], uint8_t out[], size_t length)
46
0
   {
47
0
   verify_key_set(m_state.empty() == false);
48
49
0
   while(length >= m_shake_rate - m_buf_pos)
50
0
      {
51
0
      xor_buf(out, in, &m_buffer[m_buf_pos], m_shake_rate - m_buf_pos);
52
0
      length -= (m_shake_rate - m_buf_pos);
53
0
      in += (m_shake_rate - m_buf_pos);
54
0
      out += (m_shake_rate - m_buf_pos);
55
56
0
      SHA_3::permute(m_state.data());
57
0
      copy_out_le(m_buffer.data(), m_shake_rate, m_state.data());
58
59
0
      m_buf_pos = 0;
60
0
      }
61
0
   xor_buf(out, in, &m_buffer[m_buf_pos], length);
62
0
   m_buf_pos += length;
63
0
   }
64
65
void SHAKE_Cipher::write_keystream(uint8_t out[], size_t length)
66
0
   {
67
0
   verify_key_set(m_state.empty() == false);
68
69
0
   if(m_buf_pos > 0)
70
0
      {
71
0
      const size_t take = std::min(length, m_shake_rate - m_buf_pos);
72
0
      copy_mem(out, &m_buffer[m_buf_pos], take);
73
0
      out += take;
74
0
      length -= take;
75
0
      m_buf_pos += take;
76
77
0
      if(m_buf_pos == m_shake_rate)
78
0
         {
79
0
         SHA_3::permute(m_state.data());
80
0
         m_buf_pos = 0;
81
0
         }
82
0
      }
83
84
0
   if(length == 0)
85
0
      return;
86
87
0
   BOTAN_ASSERT_NOMSG(m_buf_pos == 0);
88
89
0
   while(length >= m_shake_rate)
90
0
      {
91
0
      copy_out_le(out, m_shake_rate, m_state.data());
92
0
      SHA_3::permute(m_state.data());
93
0
      length -= m_shake_rate;
94
0
      out += m_shake_rate;
95
0
      }
96
97
0
   copy_out_le(m_buffer.data(), m_shake_rate, m_state.data());
98
99
0
   copy_mem(out, &m_buffer[0], length);
100
0
   m_buf_pos += length;
101
0
   }
102
103
void SHAKE_Cipher::key_schedule(const uint8_t key[], size_t length)
104
0
   {
105
0
   const size_t SHAKE_BITRATE = m_shake_rate*8;
106
0
   m_state.resize(25);
107
0
   m_buffer.resize(m_shake_rate);
108
0
   zeroise(m_state);
109
110
0
   const size_t S_pos = SHA_3::absorb(SHAKE_BITRATE, m_state, 0, key, length);
111
0
   SHA_3::finish(SHAKE_BITRATE, m_state, S_pos, 0x1F, 0x80);
112
0
   copy_out_le(m_buffer.data(), m_buffer.size(), m_state.data());
113
0
   m_buf_pos = 0;
114
0
   }
115
116
Key_Length_Specification SHAKE_Cipher::key_spec() const
117
0
   {
118
0
   return Key_Length_Specification(1, 160);
119
0
   }
120
121
0
SHAKE_128_Cipher::SHAKE_128_Cipher() : SHAKE_Cipher((1600-256)/8) {}
122
0
SHAKE_256_Cipher::SHAKE_256_Cipher() : SHAKE_Cipher((1600-512)/8) {}
123
124
}