Line | Count | Source (jump to first uncovered line) |
1 | | // poly1305.h - written and placed in the public domain by Jeffrey Walton and Jean-Pierre Munch |
2 | | // Based on Andy Polyakov's Base-2^26 scalar multiplication implementation. |
3 | | // For more information, see https://www.openssl.org/~appro/cryptogams/. |
4 | | |
5 | | // The library added Bernstein's Poly1305 classes at Crypto++ 6.0. The IETF |
6 | | // uses a slightly different implementation than Bernstein, and the IETF |
7 | | // classes were added at Crypto++ 8.1. We wanted to maintain ABI compatibility |
8 | | // at the 8.1 release so the original Poly1305 classes were not disturbed. |
9 | | // Instead new classes were added for IETF Poly1305. The back-end implementation |
10 | | // shares code as expected, however. |
11 | | |
12 | | /// \file poly1305.h |
13 | | /// \brief Classes for Poly1305 message authentication code |
14 | | /// \details Poly1305-AES is a state-of-the-art message-authentication code suitable for a wide |
15 | | /// variety of applications. Poly1305-AES computes a 16-byte authenticator of a variable-length |
16 | | /// message, using a 16-byte AES key, a 16-byte additional key, and a 16-byte nonce. |
17 | | /// \details Crypto++ also supplies the IETF's version of Poly1305. It is a slightly different |
18 | | /// algorithm than Bernstein's version. |
19 | | /// \sa Daniel J. Bernstein <A HREF="http://cr.yp.to/mac/poly1305-20050329.pdf">The Poly1305-AES |
20 | | /// Message-Authentication Code (20050329)</A>, <a href="http://tools.ietf.org/html/rfc8439">RFC |
21 | | /// 8439, ChaCha20 and Poly1305 for IETF Protocols</a> and Andy Polyakov <A |
22 | | /// HREF="http://www.openssl.org/blog/blog/2016/02/15/poly1305-revised/">Poly1305 Revised</A> |
23 | | /// \since Poly1305 since Crypto++ 6.0, Poly1305TLS since Crypto++ 8.1 |
24 | | |
25 | | #ifndef CRYPTOPP_POLY1305_H |
26 | | #define CRYPTOPP_POLY1305_H |
27 | | |
28 | | #include "cryptlib.h" |
29 | | #include "seckey.h" |
30 | | #include "secblock.h" |
31 | | #include "argnames.h" |
32 | | #include "algparam.h" |
33 | | |
34 | | NAMESPACE_BEGIN(CryptoPP) |
35 | | |
36 | | ////////////////////////////// Bernstein Poly1305 ////////////////////////////// |
37 | | |
38 | | /// \brief Poly1305 message authentication code base class |
39 | | /// \tparam T BlockCipherDocumentation derived class with 16-byte key and 16-byte blocksize |
40 | | /// \details Poly1305_Base is the base class of Bernstein's Poly1305 algorithm. |
41 | | /// \since Crypto++ 6.0 |
42 | | template <class T> |
43 | | class CRYPTOPP_NO_VTABLE Poly1305_Base : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 16>, public MessageAuthenticationCode |
44 | | { |
45 | | CRYPTOPP_COMPILE_ASSERT(T::DEFAULT_KEYLENGTH == 16); |
46 | | CRYPTOPP_COMPILE_ASSERT(T::BLOCKSIZE == 16); |
47 | | |
48 | | public: |
49 | 0 | static std::string StaticAlgorithmName() {return std::string("Poly1305(") + T::StaticAlgorithmName() + ")";} |
50 | | |
51 | | CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE); |
52 | | CRYPTOPP_CONSTANT(BLOCKSIZE=T::BLOCKSIZE); |
53 | | |
54 | 0 | virtual ~Poly1305_Base() {} |
55 | 0 | Poly1305_Base() : m_idx(0), m_used(true) {} |
56 | | |
57 | | void Resynchronize (const byte *iv, int ivLength=-1); |
58 | | void GetNextIV (RandomNumberGenerator &rng, byte *iv); |
59 | | |
60 | | void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); |
61 | | void Update(const byte *input, size_t length); |
62 | | void TruncatedFinal(byte *mac, size_t size); |
63 | | void Restart(); |
64 | | |
65 | 0 | unsigned int BlockSize() const {return BLOCKSIZE;} |
66 | 0 | unsigned int DigestSize() const {return DIGESTSIZE;} |
67 | | |
68 | | std::string AlgorithmProvider() const; |
69 | | |
70 | | protected: |
71 | | // TODO: No longer needed. Remove at next major version bump |
72 | | void HashBlocks(const byte *input, size_t length, word32 padbit); |
73 | | void HashFinal(byte *mac, size_t length); |
74 | | |
75 | | typename T::Encryption m_cipher; |
76 | | |
77 | | // Accumulated hash, clamped r-key, and encrypted nonce |
78 | | FixedSizeAlignedSecBlock<word32, 5> m_h; |
79 | | FixedSizeAlignedSecBlock<word32, 4> m_r; |
80 | | FixedSizeAlignedSecBlock<word32, 4> m_n; |
81 | | |
82 | | // Accumulated message bytes and index |
83 | | FixedSizeAlignedSecBlock<byte, BLOCKSIZE> m_acc, m_nk; |
84 | | size_t m_idx; |
85 | | |
86 | | // Track nonce reuse; assert in debug but continue |
87 | | bool m_used; |
88 | | }; |
89 | | |
90 | | /// \brief Poly1305 message authentication code |
91 | | /// \tparam T class derived from BlockCipherDocumentation with 16-byte key and 16-byte blocksize |
92 | | /// \details Poly1305-AES is a state-of-the-art message-authentication code suitable for a wide |
93 | | /// variety of applications. Poly1305-AES computes a 16-byte authenticator of a variable-length |
94 | | /// message, using a 16-byte AES key, a 16-byte additional key, and a 16-byte nonce. |
95 | | /// \details The key is 32 bytes and a concatenation <tt>key = {k,s}</tt>, where |
96 | | /// <tt>k</tt> is the AES key and <tt>r</tt> is additional key that gets clamped. |
97 | | /// The key is clamped internally so there is no need to perform the operation |
98 | | /// before setting the key. |
99 | | /// \details Each message must have a unique security context, which means either the key or nonce |
100 | | /// must be changed after each message. It can be accomplished in one of two ways. First, you |
101 | | /// can create a new Poly1305 object each time its needed. |
102 | | /// <pre> SecByteBlock key(32), nonce(16); |
103 | | /// prng.GenerateBlock(key, key.size()); |
104 | | /// prng.GenerateBlock(nonce, nonce.size()); |
105 | | /// |
106 | | /// Poly1305<AES> poly1305(key, key.size(), nonce, nonce.size()); |
107 | | /// poly1305.Update(...); |
108 | | /// poly1305.Final(...);</pre> |
109 | | /// |
110 | | /// \details Second, you can create a Poly1305 object, reuse the key, and set a fresh nonce |
111 | | /// for each message. The second and subsequent nonces can be generated using GetNextIV(). |
112 | | /// <pre> SecByteBlock key(32), nonce(16); |
113 | | /// prng.GenerateBlock(key, key.size()); |
114 | | /// prng.GenerateBlock(nonce, nonce.size()); |
115 | | /// |
116 | | /// // First message |
117 | | /// Poly1305<AES> poly1305(key, key.size()); |
118 | | /// poly1305.Resynchronize(nonce); |
119 | | /// poly1305.Update(...); |
120 | | /// poly1305.Final(...); |
121 | | /// |
122 | | /// // Second message |
123 | | /// poly1305.GetNextIV(prng, nonce); |
124 | | /// poly1305.Resynchronize(nonce); |
125 | | /// poly1305.Update(...); |
126 | | /// poly1305.Final(...); |
127 | | /// ...</pre> |
128 | | /// \warning Each message must have a unique security context. The Poly1305 class does not |
129 | | /// enforce a fresh key or nonce for each message. The source code will assert in debug |
130 | | /// builds to alert of nonce reuse. No action is taken in release builds. |
131 | | /// \sa Daniel J. Bernstein <A HREF="http://cr.yp.to/mac/poly1305-20050329.pdf">The Poly1305-AES |
132 | | /// Message-Authentication Code (20050329)</A> and Andy Polyakov <A |
133 | | /// HREF="http://www.openssl.org/blog/blog/2016/02/15/poly1305-revised/">Poly1305 Revised</A> |
134 | | /// \since Crypto++ 6.0 |
135 | | template <class T> |
136 | | class Poly1305 : public MessageAuthenticationCodeFinal<Poly1305_Base<T> > |
137 | | { |
138 | | public: |
139 | | CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=Poly1305_Base<T>::DEFAULT_KEYLENGTH); |
140 | | |
141 | | /// \brief Construct a Poly1305 |
142 | 0 | Poly1305() {} |
143 | | |
144 | | /// \brief Construct a Poly1305 |
145 | | /// \param key a byte array used to key the cipher |
146 | | /// \param keyLength the size of the byte array, in bytes |
147 | | /// \param nonce a byte array used to key the cipher |
148 | | /// \param nonceLength the size of the byte array, in bytes |
149 | | /// \details The key is 32 bytes and a concatenation <tt>key = {k,s}</tt>, where |
150 | | /// <tt>k</tt> is the AES key and <tt>r</tt> is additional key that gets clamped. |
151 | | /// The key is clamped internally so there is no need to perform the operation |
152 | | /// before setting the key. |
153 | | /// \details Each message requires a unique security context. You can use GetNextIV() |
154 | | /// and Resynchronize() to set a new nonce under a key for a message. |
155 | | Poly1305(const byte *key, size_t keyLength=DEFAULT_KEYLENGTH, const byte *nonce=NULLPTR, size_t nonceLength=0) |
156 | 0 | {this->SetKey(key, keyLength, MakeParameters(Name::IV(), ConstByteArrayParameter(nonce, nonceLength)));} |
157 | | }; |
158 | | |
159 | | ////////////////////////////// IETF Poly1305 ////////////////////////////// |
160 | | |
161 | | /// \brief Poly1305-TLS message authentication code base class |
162 | | /// \details Poly1305TLS_Base is the base class of the IETF's Poly1305 algorithm. |
163 | | /// \since Crypto++ 8.1 |
164 | | class Poly1305TLS_Base : public FixedKeyLength<32>, public MessageAuthenticationCode |
165 | | { |
166 | | public: |
167 | 0 | static std::string StaticAlgorithmName() {return std::string("Poly1305TLS");} |
168 | | CRYPTOPP_CONSTANT(DIGESTSIZE=16); |
169 | | CRYPTOPP_CONSTANT(BLOCKSIZE=16); |
170 | | |
171 | 40 | virtual ~Poly1305TLS_Base() {} |
172 | 40 | Poly1305TLS_Base() {} |
173 | | |
174 | | void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); |
175 | | void Update(const byte *input, size_t length); |
176 | | void TruncatedFinal(byte *mac, size_t size); |
177 | | void Restart(); |
178 | | |
179 | 0 | unsigned int BlockSize() const {return BLOCKSIZE;} |
180 | 13 | unsigned int DigestSize() const {return DIGESTSIZE;} |
181 | | |
182 | | protected: |
183 | | // Accumulated hash, clamped r-key, and encrypted nonce |
184 | | FixedSizeAlignedSecBlock<word32, 5> m_h; |
185 | | FixedSizeAlignedSecBlock<word32, 4> m_r; |
186 | | FixedSizeAlignedSecBlock<word32, 4> m_n; |
187 | | |
188 | | // Accumulated message bytes and index |
189 | | FixedSizeAlignedSecBlock<byte, BLOCKSIZE> m_acc; |
190 | | size_t m_idx; |
191 | | }; |
192 | | |
193 | | /// \brief Poly1305-TLS message authentication code |
194 | | /// \details This is the IETF's variant of Bernstein's Poly1305 from RFC 8439. |
195 | | /// IETF Poly1305 is called Poly1305TLS in the Crypto++ library. It is |
196 | | /// _slightly_ different from the Bernstein implementation. Poly1305-TLS |
197 | | /// can be used for cipher suites |
198 | | /// <tt>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>, |
199 | | /// <tt>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</tt>, and |
200 | | /// <tt>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>. |
201 | | /// \details The key is 32 bytes and a concatenation <tt>key = {r,s}</tt>, where |
202 | | /// <tt>r</tt> is additional key that gets clamped and <tt>s</tt> is the nonce. |
203 | | /// The key is clamped internally so there is no need to perform the operation |
204 | | /// before setting the key. |
205 | | /// \details Each message must have a unique security context, which means the key |
206 | | /// must be changed after each message. It can be accomplished in one of two ways. |
207 | | /// First, you can create a new Poly1305 object with a new key each time its needed. |
208 | | /// <pre> SecByteBlock key(32); |
209 | | /// prng.GenerateBlock(key, key.size()); |
210 | | /// |
211 | | /// Poly1305TLS poly1305(key, key.size()); |
212 | | /// poly1305.Update(...); |
213 | | /// poly1305.Final(...);</pre> |
214 | | /// |
215 | | /// \details Second, you can create a Poly1305 object, and use a new key for each |
216 | | /// message. The keys can be generated directly using a RandomNumberGenerator() |
217 | | /// derived class. |
218 | | /// <pre> SecByteBlock key(32); |
219 | | /// prng.GenerateBlock(key, key.size()); |
220 | | /// |
221 | | /// // First message |
222 | | /// Poly1305TLS poly1305(key, key.size()); |
223 | | /// poly1305.Update(...); |
224 | | /// poly1305.Final(...); |
225 | | /// |
226 | | /// // Second message |
227 | | /// prng.GenerateBlock(key, key.size()); |
228 | | /// poly1305.SetKey(key, key.size()); |
229 | | /// poly1305.Update(...); |
230 | | /// poly1305.Final(...); |
231 | | /// ...</pre> |
232 | | /// \warning Each message must have a unique security context. The Poly1305-TLS class |
233 | | /// does not enforce a fresh key or nonce for each message. |
234 | | /// \since Crypto++ 8.1 |
235 | | /// \sa MessageAuthenticationCode(), <a href="http://tools.ietf.org/html/rfc8439">RFC |
236 | | /// 8439, ChaCha20 and Poly1305 for IETF Protocols</a> |
237 | | DOCUMENTED_TYPEDEF(MessageAuthenticationCodeFinal<Poly1305TLS_Base>, Poly1305TLS); |
238 | | |
239 | | NAMESPACE_END |
240 | | |
241 | | #endif // CRYPTOPP_POLY1305_H |