aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/modes/mode_pad/mode_pad.h
blob: b0e4a3cfae064324d4cd8aab763973a290f68f9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
* CBC Padding Methods
* (C) 1999-2008,2013 Jack Lloyd
* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#ifndef BOTAN_MODE_PADDING_H_
#define BOTAN_MODE_PADDING_H_

#include <botan/secmem.h>
#include <string>

BOTAN_FUTURE_INTERNAL_HEADER(mode_pad.h)

namespace Botan {

/**
* Block Cipher Mode Padding Method
* This class is pretty limited, it cannot deal well with
* randomized padding methods, or any padding method that
* wants to add more than one block. For instance, it should
* be possible to define cipher text stealing mode as simply
* a padding mode for CBC, which happens to consume the last
* two block (and requires use of the block cipher).
*/
class BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod
   {
   public:
      /**
      * Add padding bytes to buffer.
      * @param buffer data to pad
      * @param final_block_bytes size of the final block in bytes
      * @param block_size size of each block in bytes
      */
      virtual void add_padding(secure_vector<uint8_t>& buffer,
                               size_t final_block_bytes,
                               size_t block_size) const = 0;

      /**
      * Remove padding bytes from block
      * @param block the last block
      * @param len the size of the block in bytes
      * @return number of data bytes, or if the padding is invalid returns len
      */
      virtual size_t unpad(const uint8_t block[], size_t len) const = 0;

      /**
      * @param block_size of the cipher
      * @return valid block size for this padding mode
      */
      virtual bool valid_blocksize(size_t block_size) const = 0;

      /**
      * @return name of the mode
      */
      virtual std::string name() const = 0;

      /**
      * virtual destructor
      */
      virtual ~BlockCipherModePaddingMethod() = default;
   };

/**
* PKCS#7 Padding
*/
class BOTAN_PUBLIC_API(2,0) PKCS7_Padding final : public BlockCipherModePaddingMethod
   {
   public:
      void add_padding(secure_vector<uint8_t>& buffer,
                       size_t final_block_bytes,
                       size_t block_size) const override;

      size_t unpad(const uint8_t[], size_t) const override;

      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }

      std::string name() const override { return "PKCS7"; }
   };

/**
* ANSI X9.23 Padding
*/
class BOTAN_PUBLIC_API(2,0) ANSI_X923_Padding final : public BlockCipherModePaddingMethod
   {
   public:
      void add_padding(secure_vector<uint8_t>& buffer,
                       size_t final_block_bytes,
                       size_t block_size) const override;

      size_t unpad(const uint8_t[], size_t) const override;

      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }

      std::string name() const override { return "X9.23"; }
   };

/**
* One And Zeros Padding (ISO/IEC 9797-1, padding method 2)
*/
class BOTAN_PUBLIC_API(2,0) OneAndZeros_Padding final : public BlockCipherModePaddingMethod
   {
   public:
      void add_padding(secure_vector<uint8_t>& buffer,
                       size_t final_block_bytes,
                       size_t block_size) const override;

      size_t unpad(const uint8_t[], size_t) const override;

      bool valid_blocksize(size_t bs) const override { return (bs > 2); }

      std::string name() const override { return "OneAndZeros"; }
   };

/**
* ESP Padding (RFC 4304)
*/
class BOTAN_PUBLIC_API(2,0) ESP_Padding final : public BlockCipherModePaddingMethod
   {
   public:
      void add_padding(secure_vector<uint8_t>& buffer,
                       size_t final_block_bytes,
                       size_t block_size) const override;

      size_t unpad(const uint8_t[], size_t) const override;

      bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }

      std::string name() const override { return "ESP"; }
   };

/**
* Null Padding
*/
class BOTAN_PUBLIC_API(2,0) Null_Padding final : public BlockCipherModePaddingMethod
   {
   public:
      void add_padding(secure_vector<uint8_t>&, size_t, size_t) const override
         {
         /* no padding */
         }

      size_t unpad(const uint8_t[], size_t size) const override { return size; }

      bool valid_blocksize(size_t) const override { return true; }

      std::string name() const override { return "NoPadding"; }
   };

/**
* Get a block cipher padding mode by name (eg "NoPadding" or "PKCS7")
* @param algo_spec block cipher padding mode name
*/
BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec);

}

#endif