xref: /netbsd-src/external/bsd/elftosb/dist/common/AESKey.h (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
1*993229b6Sjkunz /*
2*993229b6Sjkunz  * File:	AESKey.h
3*993229b6Sjkunz  *
4*993229b6Sjkunz  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5*993229b6Sjkunz  * See included license file for license details.
6*993229b6Sjkunz  */
7*993229b6Sjkunz #if !defined(_AESKey_h_)
8*993229b6Sjkunz #define _AESKey_h_
9*993229b6Sjkunz 
10*993229b6Sjkunz #include "stdafx.h"
11*993229b6Sjkunz #include <string.h>
12*993229b6Sjkunz #include <iostream>
13*993229b6Sjkunz #include "Random.h"
14*993229b6Sjkunz 
15*993229b6Sjkunz //! An AES-128 key is 128 bits, or 16 bytes.
16*993229b6Sjkunz typedef uint8_t aes128_key_t[16];
17*993229b6Sjkunz 
18*993229b6Sjkunz /*!
19*993229b6Sjkunz  * \brief Base class for AESKey<S>.
20*993229b6Sjkunz  *
21*993229b6Sjkunz  * This class implements some bigger, non-template methods used in the
22*993229b6Sjkunz  * AESKey<S> templated subclass.
23*993229b6Sjkunz  */
24*993229b6Sjkunz class AESKeyBase
25*993229b6Sjkunz {
26*993229b6Sjkunz public:
27*993229b6Sjkunz 	//! \brief Reads hex encoded data from \a stream.
28*993229b6Sjkunz 	void _readFromStream(std::istream & stream, unsigned bytes, uint8_t * buffer);
29*993229b6Sjkunz 
30*993229b6Sjkunz 	//! \brief Writes hex encoded data to \a stream.
31*993229b6Sjkunz 	void _writeToStream(std::ostream & stream, unsigned bytes, const uint8_t * buffer);
32*993229b6Sjkunz };
33*993229b6Sjkunz 
34*993229b6Sjkunz /*!
35*993229b6Sjkunz  * \brief Generic AES key class.
36*993229b6Sjkunz  *
37*993229b6Sjkunz  * The template parameter \a S is the number of bits in the key.
38*993229b6Sjkunz  *
39*993229b6Sjkunz  * The underlying key type can be accessed like this: AESKey<128>::key_t
40*993229b6Sjkunz  *
41*993229b6Sjkunz  * When a key instance is destroyed, it erases the key data by setting it
42*993229b6Sjkunz  * to all zeroes.
43*993229b6Sjkunz  *
44*993229b6Sjkunz  * \todo Add a way to allow only key sizes of 128, 192, and 256 bits.
45*993229b6Sjkunz  * \todo Find a cross platform way to prevent the key data from being written
46*993229b6Sjkunz  *		to the VM swapfile.
47*993229b6Sjkunz  *
48*993229b6Sjkunz  * AESKey<128> key = AESKey<128>::readFromStream(s);
49*993229b6Sjkunz  */
50*993229b6Sjkunz template <int S>
51*993229b6Sjkunz class AESKey : public AESKeyBase
52*993229b6Sjkunz {
53*993229b6Sjkunz public:
54*993229b6Sjkunz 	//! Type for this size of AES key.
55*993229b6Sjkunz 	typedef uint8_t key_t[S/8];
56*993229b6Sjkunz 
57*993229b6Sjkunz public:
58*993229b6Sjkunz 	//! \brief Default constructor.
59*993229b6Sjkunz 	//!
60*993229b6Sjkunz 	//! Initializes the key to 0.
AESKey()61*993229b6Sjkunz 	AESKey()
62*993229b6Sjkunz 	{
63*993229b6Sjkunz 		memset(m_key, 0, sizeof(m_key));
64*993229b6Sjkunz 	}
65*993229b6Sjkunz 
66*993229b6Sjkunz 	//! \brief Constructor taking a key value reference.
AESKey(const key_t & key)67*993229b6Sjkunz 	AESKey(const key_t & key)
68*993229b6Sjkunz 	{
69*993229b6Sjkunz 		memcpy(m_key, &key, sizeof(m_key));
70*993229b6Sjkunz 	}
71*993229b6Sjkunz 
72*993229b6Sjkunz 	// \brief Constructor taking a key value pointer.
AESKey(const key_t * key)73*993229b6Sjkunz 	AESKey(const key_t * key)
74*993229b6Sjkunz 	{
75*993229b6Sjkunz 		memcpy(m_key, key, sizeof(m_key));
76*993229b6Sjkunz 	}
77*993229b6Sjkunz 
78*993229b6Sjkunz 	//! \brief Constructor, reads key from stream in hex format.
AESKey(std::istream & stream)79*993229b6Sjkunz 	AESKey(std::istream & stream)
80*993229b6Sjkunz 	{
81*993229b6Sjkunz 		readFromStream(stream);
82*993229b6Sjkunz 	}
83*993229b6Sjkunz 
84*993229b6Sjkunz 	//! \brief Copy constructor.
AESKey(const AESKey<S> & other)85*993229b6Sjkunz 	AESKey(const AESKey<S> & other)
86*993229b6Sjkunz 	{
87*993229b6Sjkunz 		memcpy(m_key, other.m_key, sizeof(m_key));
88*993229b6Sjkunz 	}
89*993229b6Sjkunz 
90*993229b6Sjkunz 	//! \brief Destructor.
91*993229b6Sjkunz 	//!
92*993229b6Sjkunz 	//! Sets the key value to zero.
~AESKey()93*993229b6Sjkunz 	~AESKey()
94*993229b6Sjkunz 	{
95*993229b6Sjkunz 		memset(m_key, 0, sizeof(m_key));
96*993229b6Sjkunz 	}
97*993229b6Sjkunz 
98*993229b6Sjkunz 	//! \brief Set to the key to a randomly generated value.
randomize()99*993229b6Sjkunz 	void randomize()
100*993229b6Sjkunz 	{
101*993229b6Sjkunz 		RandomNumberGenerator rng;
102*993229b6Sjkunz 		rng.generateBlock(m_key, sizeof(m_key));
103*993229b6Sjkunz 	}
104*993229b6Sjkunz 
105*993229b6Sjkunz 	//! \brief Reads the key from a hex encoded data stream.
readFromStream(std::istream & stream)106*993229b6Sjkunz 	void readFromStream(std::istream & stream)
107*993229b6Sjkunz 	{
108*993229b6Sjkunz 		_readFromStream(stream, S/8, reinterpret_cast<uint8_t*>(&m_key));
109*993229b6Sjkunz 	}
110*993229b6Sjkunz 
111*993229b6Sjkunz 	//! \brief Writes the key to a data stream in hex encoded format.
writeToStream(std::ostream & stream)112*993229b6Sjkunz 	void writeToStream(std::ostream & stream)
113*993229b6Sjkunz 	{
114*993229b6Sjkunz 		_writeToStream(stream, S/8, reinterpret_cast<uint8_t*>(&m_key));
115*993229b6Sjkunz 	}
116*993229b6Sjkunz 
117*993229b6Sjkunz 	//! \name Key accessors
118*993229b6Sjkunz 	//@{
getKey()119*993229b6Sjkunz 	inline const key_t & getKey() const { return m_key; }
getKey(key_t * key)120*993229b6Sjkunz 	inline void getKey(key_t * key) const { memcpy(key, m_key, sizeof(m_key)); }
121*993229b6Sjkunz 
setKey(const key_t & key)122*993229b6Sjkunz 	inline void setKey(const key_t & key) { memcpy(m_key, &key, sizeof(m_key)); }
setKey(const key_t * key)123*993229b6Sjkunz 	inline void setKey(const key_t * key) { memcpy(m_key, key, sizeof(m_key)); }
setKey(const AESKey<S> & key)124*993229b6Sjkunz 	inline void setKey(const AESKey<S> & key) { memcpy(m_key, key.m_key, sizeof(m_key)); }
125*993229b6Sjkunz 	//@}
126*993229b6Sjkunz 
127*993229b6Sjkunz 	//! \name Operators
128*993229b6Sjkunz 	//@{
129*993229b6Sjkunz 	const AESKey<S> & operator = (const AESKey<S> & key) { setKey(key); return *this; }
130*993229b6Sjkunz 	const AESKey<S> & operator = (const key_t & key) { setKey(key); return *this; }
131*993229b6Sjkunz 	const AESKey<S> & operator = (const key_t * key) { setKey(key); return *this; }
132*993229b6Sjkunz 
133*993229b6Sjkunz 	operator const key_t & () const { return m_key; }
134*993229b6Sjkunz 	operator const key_t * () const { return m_key; }
135*993229b6Sjkunz 	//@}
136*993229b6Sjkunz 
137*993229b6Sjkunz protected:
138*993229b6Sjkunz 	key_t m_key;	//!< The key value.
139*993229b6Sjkunz };
140*993229b6Sjkunz 
141*993229b6Sjkunz //! Standard type definition for an AES-128 key.
142*993229b6Sjkunz typedef AESKey<128> AES128Key;
143*993229b6Sjkunz 
144*993229b6Sjkunz #endif // _AESKey_h_
145