summaryrefslogtreecommitdiffstats
path: root/common/AESKey.h
blob: b92b1aed57c4f33d102645866d15465375f81558 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * File:	AESKey.h
 *
 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
 * See included license file for license details.
 */
#if !defined(_AESKey_h_)
#define _AESKey_h_

#include "stdafx.h"
#include <string.h>
#include <iostream>
#include "Random.h"

//! An AES-128 key is 128 bits, or 16 bytes.
typedef uint8_t aes128_key_t[16];

/*!
 * \brief Base class for AESKey<S>.
 *
 * This class implements some bigger, non-template methods used in the
 * AESKey<S> templated subclass.
 */
class AESKeyBase
{
public:
	//! \brief Reads hex encoded data from \a stream.
	void _readFromStream(std::istream & stream, unsigned bytes, uint8_t * buffer);
	
	//! \brief Writes hex encoded data to \a stream.
	void _writeToStream(std::ostream & stream, unsigned bytes, const uint8_t * buffer);
};

/*!
 * \brief Generic AES key class.
 *
 * The template parameter \a S is the number of bits in the key.
 *
 * The underlying key type can be accessed like this: AESKey<128>::key_t
 *
 * When a key instance is destroyed, it erases the key data by setting it
 * to all zeroes.
 *
 * \todo Add a way to allow only key sizes of 128, 192, and 256 bits.
 * \todo Find a cross platform way to prevent the key data from being written
 *		to the VM swapfile.
 *
 * AESKey<128> key = AESKey<128>::readFromStream(s);
 */
template <int S>
class AESKey : public AESKeyBase
{
public:
	//! Type for this size of AES key.
	typedef uint8_t key_t[S/8];
	
public:
	//! \brief Default constructor.
	//!
	//! Initializes the key to 0.
	AESKey()
	{
		memset(m_key, 0, sizeof(m_key));
	}
	
	//! \brief Constructor taking a key value reference.
	AESKey(const key_t & key)
	{
		memcpy(m_key, &key, sizeof(m_key));
	}
	
	// \brief Constructor taking a key value pointer.
	AESKey(const key_t * key)
	{
		memcpy(m_key, key, sizeof(m_key));
	}
	
	//! \brief Constructor, reads key from stream in hex format.
	AESKey(std::istream & stream)
	{
		readFromStream(stream);
	}
	
	//! \brief Copy constructor.
	AESKey(const AESKey<S> & other)
	{
		memcpy(m_key, other.m_key, sizeof(m_key));
	}
	
	//! \brief Destructor.
	//!
	//! Sets the key value to zero.
	~AESKey()
	{
		memset(m_key, 0, sizeof(m_key));
	}
	
	//! \brief Set to the key to a randomly generated value.
	void randomize()
	{
		RandomNumberGenerator rng;
		rng.generateBlock(m_key, sizeof(m_key));
	}
	
	//! \brief Reads the key from a hex encoded data stream.
	void readFromStream(std::istream & stream)
	{
		_readFromStream(stream, S/8, reinterpret_cast<uint8_t*>(&m_key));
	}
	
	//! \brief Writes the key to a data stream in hex encoded format.
	void writeToStream(std::ostream & stream)
	{
		_writeToStream(stream, S/8, reinterpret_cast<uint8_t*>(&m_key));
	}
	
	//! \name Key accessors
	//@{
	inline const key_t & getKey() const { return m_key; }
	inline void getKey(key_t * key) const { memcpy(key, m_key, sizeof(m_key)); }
	
	inline void setKey(const key_t & key) { memcpy(m_key, &key, sizeof(m_key)); }
	inline void setKey(const key_t * key) { memcpy(m_key, key, sizeof(m_key)); }
	inline void setKey(const AESKey<S> & key) { memcpy(m_key, key.m_key, sizeof(m_key)); }
	//@}
	
	//! \name Operators
	//@{
	const AESKey<S> & operator = (const AESKey<S> & key) { setKey(key); return *this; }
	const AESKey<S> & operator = (const key_t & key) { setKey(key); return *this; }
	const AESKey<S> & operator = (const key_t * key) { setKey(key); return *this; }
	
	operator const key_t & () const { return m_key; }
	operator const key_t * () const { return m_key; }
	//@}
	
protected:
	key_t m_key;	//!< The key value.
};

//! Standard type definition for an AES-128 key.
typedef AESKey<128> AES128Key;

#endif // _AESKey_h_