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