Botan  2.11.0
Crypto and TLS for C++11
base32.cpp
Go to the documentation of this file.
1 /*
2 * Base32 Encoding and Decoding
3 * (C) 2018 Erwan Chaussy
4 * (C) 2018 Jack Lloyd
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/base32.h>
10 #include <botan/internal/codec_base.h>
11 #include <botan/internal/rounding.h>
12 
13 namespace Botan {
14 
15 namespace {
16 
17 class Base32 final
18  {
19  public:
20  static inline std::string name() noexcept
21  {
22  return "base32";
23  }
24 
25  static inline size_t encoding_bytes_in() noexcept
26  {
27  return m_encoding_bytes_in;
28  }
29  static inline size_t encoding_bytes_out() noexcept
30  {
31  return m_encoding_bytes_out;
32  }
33 
34  static inline size_t decoding_bytes_in() noexcept
35  {
36  return m_encoding_bytes_out;
37  }
38  static inline size_t decoding_bytes_out() noexcept
39  {
40  return m_encoding_bytes_in;
41  }
42 
43  static inline size_t bits_consumed() noexcept
44  {
45  return m_encoding_bits;
46  }
47  static inline size_t remaining_bits_before_padding() noexcept
48  {
49  return m_remaining_bits_before_padding;
50  }
51 
52  static inline size_t encode_max_output(size_t input_length)
53  {
54  return (round_up(input_length, m_encoding_bytes_in) / m_encoding_bytes_in) * m_encoding_bytes_out;
55  }
56  static inline size_t decode_max_output(size_t input_length)
57  {
58  return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;
59  }
60 
61  static void encode(char out[8], const uint8_t in[5]) noexcept
62  {
63  out[0] = Base32::m_bin_to_base32[(in[0] & 0xF8) >> 3];
64  out[1] = Base32::m_bin_to_base32[((in[0] & 0x07) << 2) | (in[1] >> 6)];
65  out[2] = Base32::m_bin_to_base32[((in[1] & 0x3E) >> 1)];
66  out[3] = Base32::m_bin_to_base32[((in[1] & 0x01) << 4) | (in[2] >> 4)];
67  out[4] = Base32::m_bin_to_base32[((in[2] & 0x0F) << 1) | (in[3] >> 7)];
68  out[5] = Base32::m_bin_to_base32[((in[3] & 0x7C) >> 2)];
69  out[6] = Base32::m_bin_to_base32[((in[3] & 0x03) << 3) | (in[4] >> 5)];
70  out[7] = Base32::m_bin_to_base32[in[4] & 0x1F];
71  }
72 
73  static inline uint8_t lookup_binary_value(char input) noexcept
74  {
75  return Base32::m_base32_to_bin[static_cast<uint8_t>(input)];
76  }
77 
78  static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)
79  {
80  if(bin <= 0x1F)
81  {
82  return true;
83  }
84  else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
85  {
86  std::string bad_char(1, input);
87  if(bad_char == "\t")
88  { bad_char = "\\t"; }
89  else if(bad_char == "\n")
90  { bad_char = "\\n"; }
91  else if(bad_char == "\r")
92  { bad_char = "\\r"; }
93 
94  throw Invalid_Argument(
95  std::string("base32_decode: invalid base32 character '") +
96  bad_char + "'");
97  }
98  return false;
99  }
100 
101  static void decode(uint8_t* out_ptr, const uint8_t decode_buf[8])
102  {
103  out_ptr[0] = (decode_buf[0] << 3) | (decode_buf[1] >> 2);
104  out_ptr[1] = (decode_buf[1] << 6) | (decode_buf[2] << 1) | (decode_buf[3] >> 4);
105  out_ptr[2] = (decode_buf[3] << 4) | (decode_buf[4] >> 1);
106  out_ptr[3] = (decode_buf[4] << 7) | (decode_buf[5] << 2) | (decode_buf[6] >> 3);
107  out_ptr[4] = (decode_buf[6] << 5) | decode_buf[7];
108  }
109 
110  static inline size_t bytes_to_remove(size_t final_truncate)
111  {
112  return final_truncate ? (final_truncate / 2) + 1 : 0;
113  }
114 
115  private:
116  static const size_t m_encoding_bits = 5;
117  static const size_t m_remaining_bits_before_padding = 6;
118 
119 
120  static const size_t m_encoding_bytes_in = 5;
121  static const size_t m_encoding_bytes_out = 8;
122 
123 
124  static const uint8_t m_bin_to_base32[32];
125  static const uint8_t m_base32_to_bin[256];
126  };
127 
128 const uint8_t Base32::m_bin_to_base32[32] =
129  {
130  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
131  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
132  '2', '3', '4', '5', '6', '7'
133  };
134 
135 /*
136 * base32 Decoder Lookup Table
137 * Warning: assumes ASCII encodings
138 */
139 const uint8_t Base32::m_base32_to_bin[256] =
140  {
141  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
142  0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
143  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
144  0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
145  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
146  0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,
147  0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,
148  0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
149  0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
150  0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
151  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
152  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
153  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
154  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
155  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
156  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
157  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
161  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
162  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
163  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
164  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
165  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
166  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
167  };
168 
169 }
170 
171 size_t base32_encode(char out[],
172  const uint8_t in[],
173  size_t input_length,
174  size_t& input_consumed,
175  bool final_inputs)
176  {
177  return base_encode(Base32(), out, in, input_length, input_consumed, final_inputs);
178  }
179 
180 std::string base32_encode(const uint8_t input[],
181  size_t input_length)
182  {
183  return base_encode_to_string(Base32(), input, input_length);
184  }
185 
186 size_t base32_decode(uint8_t out[],
187  const char in[],
188  size_t input_length,
189  size_t& input_consumed,
190  bool final_inputs,
191  bool ignore_ws)
192  {
193  return base_decode(Base32(), out, in, input_length, input_consumed, final_inputs, ignore_ws);
194  }
195 
196 size_t base32_decode(uint8_t output[],
197  const char input[],
198  size_t input_length,
199  bool ignore_ws)
200  {
201  return base_decode_full(Base32(), output, input, input_length, ignore_ws);
202  }
203 
204 size_t base32_decode(uint8_t output[],
205  const std::string& input,
206  bool ignore_ws)
207  {
208  return base32_decode(output, input.data(), input.length(), ignore_ws);
209  }
210 
212  size_t input_length,
213  bool ignore_ws)
214  {
215  return base_decode_to_vec<secure_vector<uint8_t>>(Base32(), input, input_length, ignore_ws);
216  }
217 
218 secure_vector<uint8_t> base32_decode(const std::string& input,
219  bool ignore_ws)
220  {
221  return base32_decode(input.data(), input.size(), ignore_ws);
222  }
223 
224 }
size_t base_decode(Base &&base, uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws=true)
Definition: codec_base.h:124
int(* final)(unsigned char *, CTX *)
std::string base_encode_to_string(Base &&base, const uint8_t input[], size_t input_length)
Definition: codec_base.h:86
std::string name
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
size_t base32_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition: base32.cpp:186
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
size_t base32_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base32.cpp:171
Definition: alg_id.cpp:13
size_t base_decode_full(Base &&base, uint8_t output[], const char input[], size_t input_length, bool ignore_ws)
Definition: codec_base.h:189
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
size_t round_up(size_t n, size_t align_to)
Definition: rounding.h:21
size_t base_encode(Base &&base, char output[], const uint8_t input[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: codec_base.h:34