Botan
1.11.15
|
00001 /* 00002 * CBC Padding Methods 00003 * (C) 1999-2007,2013 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/mode_pad.h> 00009 #include <botan/exceptn.h> 00010 00011 namespace Botan { 00012 00013 /** 00014 * Get a block cipher padding method by name 00015 */ 00016 BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) 00017 { 00018 if(algo_spec == "NoPadding") 00019 return new Null_Padding; 00020 00021 if(algo_spec == "PKCS7") 00022 return new PKCS7_Padding; 00023 00024 if(algo_spec == "OneAndZeros") 00025 return new OneAndZeros_Padding; 00026 00027 if(algo_spec == "X9.23") 00028 return new ANSI_X923_Padding; 00029 00030 return nullptr; 00031 } 00032 00033 /* 00034 * Pad with PKCS #7 Method 00035 */ 00036 void PKCS7_Padding::add_padding(secure_vector<byte>& buffer, 00037 size_t last_byte_pos, 00038 size_t block_size) const 00039 { 00040 const byte pad_value = block_size - last_byte_pos; 00041 00042 for(size_t i = 0; i != pad_value; ++i) 00043 buffer.push_back(pad_value); 00044 } 00045 00046 /* 00047 * Unpad with PKCS #7 Method 00048 */ 00049 size_t PKCS7_Padding::unpad(const byte block[], size_t size) const 00050 { 00051 size_t position = block[size-1]; 00052 00053 if(position > size) 00054 throw Decoding_Error("Bad padding in " + name()); 00055 00056 for(size_t j = size-position; j != size-1; ++j) 00057 if(block[j] != position) 00058 throw Decoding_Error("Bad padding in " + name()); 00059 00060 return (size-position); 00061 } 00062 00063 /* 00064 * Pad with ANSI X9.23 Method 00065 */ 00066 void ANSI_X923_Padding::add_padding(secure_vector<byte>& buffer, 00067 size_t last_byte_pos, 00068 size_t block_size) const 00069 { 00070 const byte pad_value = block_size - last_byte_pos; 00071 00072 for(size_t i = last_byte_pos; i < block_size; ++i) 00073 buffer.push_back(0); 00074 buffer.push_back(pad_value); 00075 } 00076 00077 /* 00078 * Unpad with ANSI X9.23 Method 00079 */ 00080 size_t ANSI_X923_Padding::unpad(const byte block[], size_t size) const 00081 { 00082 size_t position = block[size-1]; 00083 if(position > size) 00084 throw Decoding_Error(name()); 00085 for(size_t j = size-position; j != size-1; ++j) 00086 if(block[j] != 0) 00087 throw Decoding_Error(name()); 00088 return (size-position); 00089 } 00090 00091 /* 00092 * Pad with One and Zeros Method 00093 */ 00094 void OneAndZeros_Padding::add_padding(secure_vector<byte>& buffer, 00095 size_t last_byte_pos, 00096 size_t block_size) const 00097 { 00098 buffer.push_back(0x80); 00099 00100 for(size_t i = last_byte_pos + 1; i % block_size; ++i) 00101 buffer.push_back(0x00); 00102 } 00103 00104 /* 00105 * Unpad with One and Zeros Method 00106 */ 00107 size_t OneAndZeros_Padding::unpad(const byte block[], size_t size) const 00108 { 00109 while(size) 00110 { 00111 if(block[size-1] == 0x80) 00112 break; 00113 if(block[size-1] != 0x00) 00114 throw Decoding_Error(name()); 00115 size--; 00116 } 00117 if(!size) 00118 throw Decoding_Error(name()); 00119 return (size-1); 00120 } 00121 00122 00123 }