xref: /netbsd-src/external/bsd/elftosb/dist/common/RijndaelCBCMAC.cpp (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
1 /*
2  * File:	RijndaelCBCMAC.cpp
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 
8 #include "RijndaelCBCMAC.h"
9 #include "rijndael.h"
10 #include <assert.h>
11 #include "Logging.h"
12 
13 void logHexArray(Logger::log_level_t level, const uint8_t * bytes, unsigned count);
14 
15 //! \param key The key to use as the CBC-MAC secret.
16 //! \param iv Initialization vector. Defaults to zero if not provided.
RijndaelCBCMAC(const AESKey<128> & key,const uint8_t * iv)17 RijndaelCBCMAC::RijndaelCBCMAC(const AESKey<128> & key, const uint8_t * iv)
18 :	m_key(key)
19 {
20 	if (iv)
21 	{
22 		memcpy(m_mac, iv, sizeof(m_mac));
23 	}
24 	else
25 	{
26 		memset(m_mac, 0, sizeof(m_mac));
27 	}
28 }
29 
30 //! \param data Pointer to data to process.
31 //! \param length Number of bytes to process. Must be evenly divisible by #BLOCK_SIZE.
update(const uint8_t * data,unsigned length)32 void RijndaelCBCMAC::update(const uint8_t * data, unsigned length)
33 {
34 	assert(length % BLOCK_SIZE == 0);
35 	unsigned blocks = length / BLOCK_SIZE;
36 	while (blocks--)
37 	{
38 		updateOneBlock(data);
39 		data += BLOCK_SIZE;
40 	}
41 }
42 
43 //! It appears that some forms of CBC-MAC encrypt the final output block again in
44 //! order to protect against a plaintext attack. This method is a placeholder for
45 //! such an operation, but it currently does nothing.
finalize()46 void RijndaelCBCMAC::finalize()
47 {
48 }
49 
50 //! On entry the current value of m_mac becomes the initialization vector
51 //! for the CBC encryption of this block. The output of the encryption then
52 //! becomes the new MAC, which is stored in m_mac.
updateOneBlock(const uint8_t * data)53 void RijndaelCBCMAC::updateOneBlock(const uint8_t * data)
54 {
55 	Rijndael cipher;
56 	cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_key, Rijndael::Key16Bytes, m_mac);
57 	cipher.blockEncrypt(data, BLOCK_SIZE * 8, m_mac);	// size is in bits
58 
59 //	Log::log(Logger::DEBUG2, "CBC-MAC output block:\n");
60 //	logHexArray(Logger::DEBUG2, (const uint8_t *)&m_mac, sizeof(m_mac));
61 }
62 
63 /*!
64  * \brief Log an array of bytes as hex.
65  */
logHexArray(Logger::log_level_t level,const uint8_t * bytes,unsigned count)66 void logHexArray(Logger::log_level_t level, const uint8_t * bytes, unsigned count)
67 {
68 	Log::SetOutputLevel leveler(level);
69 //		Log::log("    ");
70 	unsigned i;
71 	for (i = 0; i < count; ++i, ++bytes)
72 	{
73 		if ((i % 16 == 0) && (i < count - 1))
74 		{
75 			if (i != 0)
76 			{
77 				Log::log("\n");
78 			}
79 			Log::log("    0x%04x: ", i);
80 		}
81 		Log::log("%02x ", *bytes & 0xff);
82 	}
83 
84 	Log::log("\n");
85 }
86 
87