aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/modes/mode_pad/mode_pad.h
blob: af528a926ccb50672b599ca0e22df915dca58703 (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
/*
* ECB/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>

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_DLL 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<byte>& buffer,
                               size_t final_block_bytes,
                               size_t block_size) const = 0;

      /**
      * Remove padding bytes from block
      * @param block the last block
      * @param size the size of the block in bytes
      * @return number of padding bytes
      */
      virtual size_t unpad(const byte block[],
                           size_t size) 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() {}
   };

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

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

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

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

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

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

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

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

/**
* One And Zeros Padding (ISO/IEC 7816-4)
*/
class BOTAN_DLL OneAndZeros_Padding final : public BlockCipherModePaddingMethod
   {
   public:
      void add_padding(secure_vector<byte>& buffer,
                       size_t final_block_bytes,
                       size_t block_size) const override;

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

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

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

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

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

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

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

/**
* Null Padding
*/
class BOTAN_DLL Null_Padding final : public BlockCipherModePaddingMethod
   {
   public:
      void add_padding(secure_vector<byte>&, size_t, size_t) const override {}

      size_t unpad(const byte[], 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_DLL BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec);

}

#endif