Botan  1.11.15
src/lib/modes/mode_pad/mode_pad.cpp
Go to the documentation of this file.
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 }