00001
00002
00003
00004
00005
00006
00007
00008 #include <botan/x919_mac.h>
00009 #include <botan/internal/xor_buf.h>
00010 #include <algorithm>
00011
00012 namespace Botan {
00013
00014
00015
00016
00017 void ANSI_X919_MAC::add_data(const byte input[], u32bit length)
00018 {
00019 u32bit xored = std::min(8 - position, length);
00020 xor_buf(state + position, input, xored);
00021 position += xored;
00022
00023 if(position < 8) return;
00024
00025 e->encrypt(state);
00026 input += xored;
00027 length -= xored;
00028 while(length >= 8)
00029 {
00030 xor_buf(state, input, 8);
00031 e->encrypt(state);
00032 input += 8;
00033 length -= 8;
00034 }
00035
00036 xor_buf(state, input, length);
00037 position = length;
00038 }
00039
00040
00041
00042
00043 void ANSI_X919_MAC::final_result(byte mac[])
00044 {
00045 if(position)
00046 e->encrypt(state);
00047 d->decrypt(state, mac);
00048 e->encrypt(mac);
00049 state.clear();
00050 position = 0;
00051 }
00052
00053
00054
00055
00056 void ANSI_X919_MAC::key_schedule(const byte key[], u32bit length)
00057 {
00058 e->set_key(key, 8);
00059 if(length == 8) d->set_key(key, 8);
00060 else d->set_key(key + 8, 8);
00061 }
00062
00063
00064
00065
00066 void ANSI_X919_MAC::clear()
00067 {
00068 e->clear();
00069 d->clear();
00070 state.clear();
00071 position = 0;
00072 }
00073
00074 std::string ANSI_X919_MAC::name() const
00075 {
00076 return "X9.19-MAC";
00077 }
00078
00079 MessageAuthenticationCode* ANSI_X919_MAC::clone() const
00080 {
00081 return new ANSI_X919_MAC(e->clone());
00082 }
00083
00084
00085
00086
00087 ANSI_X919_MAC::ANSI_X919_MAC(BlockCipher* e_in) :
00088 MessageAuthenticationCode(e_in->BLOCK_SIZE,
00089 e_in->MINIMUM_KEYLENGTH,
00090 2*e_in->MAXIMUM_KEYLENGTH,
00091 2*e_in->KEYLENGTH_MULTIPLE),
00092 e(e_in), d(e->clone()), position(0)
00093 {
00094 if(e->name() != "DES")
00095 throw Invalid_Argument("ANSI X9.19 MAC only supports DES");
00096 }
00097
00098
00099
00100
00101 ANSI_X919_MAC::~ANSI_X919_MAC()
00102 {
00103 delete e;
00104 delete d;
00105 }
00106
00107 }