1 /*****************************************************************
3 | Neptune - Message Digests
5 | Copyright (c) 2002-2010, Axiomatic Systems, LLC.
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 ****************************************************************/
33 Portions of this code are based on the code of LibTomCrypt
34 that was released into public domain by Tom St Denis.
37 /*----------------------------------------------------------------------
39 +---------------------------------------------------------------------*/
40 #include "NptDigest.h"
43 /*----------------------------------------------------------------------
45 +---------------------------------------------------------------------*/
46 #define NPT_BASIC_DIGEST_BLOCK_SIZE 64
48 /*----------------------------------------------------------------------
50 +---------------------------------------------------------------------*/
51 #define NPT_Digest_ROL(x, y) \
52 ( (((NPT_UInt32)(x) << (y)) | (((NPT_UInt32)(x) & 0xFFFFFFFFUL) >> (32 - (y)))) & 0xFFFFFFFFUL)
53 #define NPT_Digest_ROR(x, y) \
54 ( ((((NPT_UInt32)(x)&0xFFFFFFFFUL)>>(NPT_UInt32)((y)&31)) | ((NPT_UInt32)(x)<<(NPT_UInt32)(32-((y)&31)))) & 0xFFFFFFFFUL)
56 #define NPT_Sha1_F0(x,y,z) (z ^ (x & (y ^ z)))
57 #define NPT_Sha1_F1(x,y,z) (x ^ y ^ z)
58 #define NPT_Sha1_F2(x,y,z) ((x & y) | (z & (x | y)))
59 #define NPT_Sha1_F3(x,y,z) (x ^ y ^ z)
61 #define NPT_Sha1_FF0(a,b,c,d,e,i) e = (NPT_Digest_ROL(a, 5) + NPT_Sha1_F0(b,c,d) + e + W[i] + 0x5a827999UL); b = NPT_Digest_ROL(b, 30);
62 #define NPT_Sha1_FF1(a,b,c,d,e,i) e = (NPT_Digest_ROL(a, 5) + NPT_Sha1_F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = NPT_Digest_ROL(b, 30);
63 #define NPT_Sha1_FF2(a,b,c,d,e,i) e = (NPT_Digest_ROL(a, 5) + NPT_Sha1_F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = NPT_Digest_ROL(b, 30);
64 #define NPT_Sha1_FF3(a,b,c,d,e,i) e = (NPT_Digest_ROL(a, 5) + NPT_Sha1_F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = NPT_Digest_ROL(b, 30);
66 #define NPT_Sha256_Ch(x,y,z) (z ^ (x & (y ^ z)))
67 #define NPT_Sha256_Maj(x,y,z) (((x | y) & z) | (x & y))
68 #define NPT_Sha256_S(x, n) NPT_Digest_ROR((x),(n))
69 #define NPT_Sha256_R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
70 #define NPT_Sha256_Sigma0(x) (NPT_Sha256_S(x, 2) ^ NPT_Sha256_S(x, 13) ^ NPT_Sha256_S(x, 22))
71 #define NPT_Sha256_Sigma1(x) (NPT_Sha256_S(x, 6) ^ NPT_Sha256_S(x, 11) ^ NPT_Sha256_S(x, 25))
72 #define NPT_Sha256_Gamma0(x) (NPT_Sha256_S(x, 7) ^ NPT_Sha256_S(x, 18) ^ NPT_Sha256_R(x, 3))
73 #define NPT_Sha256_Gamma1(x) (NPT_Sha256_S(x, 17) ^ NPT_Sha256_S(x, 19) ^ NPT_Sha256_R(x, 10))
76 #define NPT_Md5_F(x,y,z) (z ^ (x & (y ^ z)))
77 #define NPT_Md5_G(x,y,z) (y ^ (z & (y ^ x)))
78 #define NPT_Md5_H(x,y,z) (x ^ y ^ z)
79 #define NPT_Md5_I(x,y,z) (y ^ (x | (~z)))
81 #define NPT_Md5_FF(a,b,c,d,M,s,t) \
82 a = (a + NPT_Md5_F(b,c,d) + M + t); a = NPT_Digest_ROL(a, s) + b;
84 #define NPT_Md5_GG(a,b,c,d,M,s,t) \
85 a = (a + NPT_Md5_G(b,c,d) + M + t); a = NPT_Digest_ROL(a, s) + b;
87 #define NPT_Md5_HH(a,b,c,d,M,s,t) \
88 a = (a + NPT_Md5_H(b,c,d) + M + t); a = NPT_Digest_ROL(a, s) + b;
90 #define NPT_Md5_II(a,b,c,d,M,s,t) \
91 a = (a + NPT_Md5_I(b,c,d) + M + t); a = NPT_Digest_ROL(a, s) + b;
93 /*----------------------------------------------------------------------
95 +---------------------------------------------------------------------*/
96 class NPT_BasicDigest
: public NPT_Digest
101 // NPT_Digest methods
102 virtual NPT_Result
Update(const NPT_UInt8
* data
, NPT_Size data_size
);
106 NPT_Result
ComputeDigest(NPT_UInt32
* state
,
107 NPT_Cardinal state_count
,
109 NPT_DataBuffer
& digest
);
110 virtual void CompressBlock(const NPT_UInt8
* block
) = 0;
114 NPT_UInt32 m_Pending
;
115 NPT_UInt8 m_Buffer
[NPT_BASIC_DIGEST_BLOCK_SIZE
];
118 /*----------------------------------------------------------------------
119 | NPT_BasicDigest::NPT_BasicDigest
120 +---------------------------------------------------------------------*/
121 NPT_BasicDigest::NPT_BasicDigest() :
127 /*----------------------------------------------------------------------
128 | NPT_BasicDigest::Update
129 +---------------------------------------------------------------------*/
131 NPT_BasicDigest::Update(const NPT_UInt8
* data
, NPT_Size data_size
)
133 while (data_size
> 0) {
134 if (m_Pending
== 0 && data_size
>= NPT_BASIC_DIGEST_BLOCK_SIZE
) {
136 m_Length
+= NPT_BASIC_DIGEST_BLOCK_SIZE
* 8;
137 data
+= NPT_BASIC_DIGEST_BLOCK_SIZE
;
138 data_size
-= NPT_BASIC_DIGEST_BLOCK_SIZE
;
140 unsigned int chunk
= data_size
;
141 if (chunk
> (NPT_BASIC_DIGEST_BLOCK_SIZE
- m_Pending
)) {
142 chunk
= NPT_BASIC_DIGEST_BLOCK_SIZE
- m_Pending
;
144 NPT_CopyMemory(&m_Buffer
[m_Pending
], data
, chunk
);
148 if (m_Pending
== NPT_BASIC_DIGEST_BLOCK_SIZE
) {
149 CompressBlock(m_Buffer
);
150 m_Length
+= 8 * NPT_BASIC_DIGEST_BLOCK_SIZE
;
160 /*----------------------------------------------------------------------
161 | NPT_BasicDigest::ComputeDigest
162 +---------------------------------------------------------------------*/
164 NPT_BasicDigest::ComputeDigest(NPT_UInt32
* state
,
165 NPT_Cardinal state_count
,
167 NPT_DataBuffer
& digest
)
169 // increase the length of the message
170 m_Length
+= m_Pending
* 8;
172 // append the '1' bit
173 m_Buffer
[m_Pending
++] = 0x80;
175 // if there isn't enough space left for the size (8 bytes), then compress.
176 // then we can fall back to padding zeros and length encoding as normal.
177 if (m_Pending
> NPT_BASIC_DIGEST_BLOCK_SIZE
-8) {
178 while (m_Pending
< NPT_BASIC_DIGEST_BLOCK_SIZE
) {
179 m_Buffer
[m_Pending
++] = 0;
181 CompressBlock(m_Buffer
);
185 // pad with zeroes up until the length
186 while (m_Pending
< NPT_BASIC_DIGEST_BLOCK_SIZE
-8) {
187 m_Buffer
[m_Pending
++] = 0;
192 NPT_BytesFromInt64Be(&m_Buffer
[NPT_BASIC_DIGEST_BLOCK_SIZE
-8], m_Length
);
194 NPT_BytesFromInt64Le(&m_Buffer
[NPT_BASIC_DIGEST_BLOCK_SIZE
-8], m_Length
);
196 CompressBlock(m_Buffer
);
199 digest
.SetDataSize(4*state_count
);
200 NPT_UInt8
* out
= digest
.UseData();
202 for (unsigned int i
= 0; i
< state_count
; i
++) {
203 NPT_BytesFromInt32Be(out
, state
[i
]);
207 for (unsigned int i
= 0; i
< state_count
; i
++) {
208 NPT_BytesFromInt32Le(out
, state
[i
]);
215 /*----------------------------------------------------------------------
217 +---------------------------------------------------------------------*/
218 class NPT_Sha1Digest
: public NPT_BasicDigest
223 // NPT_Digest methods
224 virtual NPT_Result
GetDigest(NPT_DataBuffer
& digest
);
225 virtual unsigned int GetSize() { return 20; }
229 virtual void CompressBlock(const NPT_UInt8
* block
);
232 NPT_UInt32 m_State
[5];
235 /*----------------------------------------------------------------------
236 | NPT_Sha1Digest::NPT_Sha1Digest
237 +---------------------------------------------------------------------*/
238 NPT_Sha1Digest::NPT_Sha1Digest()
240 m_State
[0] = 0x67452301UL
;
241 m_State
[1] = 0xefcdab89UL
;
242 m_State
[2] = 0x98badcfeUL
;
243 m_State
[3] = 0x10325476UL
;
244 m_State
[4] = 0xc3d2e1f0UL
;
247 /*----------------------------------------------------------------------
248 | NPT_Sha1Digest::CompressBlock
249 +---------------------------------------------------------------------*/
251 NPT_Sha1Digest::CompressBlock(const NPT_UInt8
* block
)
253 NPT_UInt32 a
,b
,c
,d
,e
,t
,W
[80];
255 // copy the 512-bit block into W[0..15]
256 for (unsigned int i
= 0; i
< 16; i
++) {
257 W
[i
] = NPT_BytesToInt32Be(&block
[4*i
]);
260 // copy the state to local variables
269 for (i
= 16; i
< 80; i
++) {
270 W
[i
] = NPT_Digest_ROL(W
[i
-3] ^ W
[i
-8] ^ W
[i
-14] ^ W
[i
-16], 1);
274 for (i
= 0; i
< 20; ) {
275 NPT_Sha1_FF0(a
,b
,c
,d
,e
,i
++); t
= e
; e
= d
; d
= c
; c
= b
; b
= a
; a
= t
;
279 NPT_Sha1_FF1(a
,b
,c
,d
,e
,i
++); t
= e
; e
= d
; d
= c
; c
= b
; b
= a
; a
= t
;
283 NPT_Sha1_FF2(a
,b
,c
,d
,e
,i
++); t
= e
; e
= d
; d
= c
; c
= b
; b
= a
; a
= t
;
287 NPT_Sha1_FF3(a
,b
,c
,d
,e
,i
++); t
= e
; e
= d
; d
= c
; c
= b
; b
= a
; a
= t
;
290 // store the variables back into the state
298 /*----------------------------------------------------------------------
299 | NPT_Sha1Digest::GetDigest
300 +---------------------------------------------------------------------*/
302 NPT_Sha1Digest::GetDigest(NPT_DataBuffer
& digest
)
304 return ComputeDigest(m_State
, 5, true, digest
);
307 /*----------------------------------------------------------------------
309 +---------------------------------------------------------------------*/
310 static const NPT_UInt32 NPT_Sha256_K
[64] = {
311 0x428a2f98UL
, 0x71374491UL
, 0xb5c0fbcfUL
, 0xe9b5dba5UL
, 0x3956c25bUL
,
312 0x59f111f1UL
, 0x923f82a4UL
, 0xab1c5ed5UL
, 0xd807aa98UL
, 0x12835b01UL
,
313 0x243185beUL
, 0x550c7dc3UL
, 0x72be5d74UL
, 0x80deb1feUL
, 0x9bdc06a7UL
,
314 0xc19bf174UL
, 0xe49b69c1UL
, 0xefbe4786UL
, 0x0fc19dc6UL
, 0x240ca1ccUL
,
315 0x2de92c6fUL
, 0x4a7484aaUL
, 0x5cb0a9dcUL
, 0x76f988daUL
, 0x983e5152UL
,
316 0xa831c66dUL
, 0xb00327c8UL
, 0xbf597fc7UL
, 0xc6e00bf3UL
, 0xd5a79147UL
,
317 0x06ca6351UL
, 0x14292967UL
, 0x27b70a85UL
, 0x2e1b2138UL
, 0x4d2c6dfcUL
,
318 0x53380d13UL
, 0x650a7354UL
, 0x766a0abbUL
, 0x81c2c92eUL
, 0x92722c85UL
,
319 0xa2bfe8a1UL
, 0xa81a664bUL
, 0xc24b8b70UL
, 0xc76c51a3UL
, 0xd192e819UL
,
320 0xd6990624UL
, 0xf40e3585UL
, 0x106aa070UL
, 0x19a4c116UL
, 0x1e376c08UL
,
321 0x2748774cUL
, 0x34b0bcb5UL
, 0x391c0cb3UL
, 0x4ed8aa4aUL
, 0x5b9cca4fUL
,
322 0x682e6ff3UL
, 0x748f82eeUL
, 0x78a5636fUL
, 0x84c87814UL
, 0x8cc70208UL
,
323 0x90befffaUL
, 0xa4506cebUL
, 0xbef9a3f7UL
, 0xc67178f2UL
326 /*----------------------------------------------------------------------
328 +---------------------------------------------------------------------*/
329 class NPT_Sha256Digest
: public NPT_BasicDigest
334 // NPT_Digest methods
335 virtual NPT_Result
GetDigest(NPT_DataBuffer
& digest
);
336 virtual unsigned int GetSize() { return 32; }
340 virtual void CompressBlock(const NPT_UInt8
* block
);
343 NPT_UInt32 m_State
[8];
346 /*----------------------------------------------------------------------
347 | NPT_Sha256Digest::NPT_Sha256Digest
348 +---------------------------------------------------------------------*/
349 NPT_Sha256Digest::NPT_Sha256Digest()
351 m_State
[0] = 0x6A09E667UL
;
352 m_State
[1] = 0xBB67AE85UL
;
353 m_State
[2] = 0x3C6EF372UL
;
354 m_State
[3] = 0xA54FF53AUL
;
355 m_State
[4] = 0x510E527FUL
;
356 m_State
[5] = 0x9B05688CUL
;
357 m_State
[6] = 0x1F83D9ABUL
;
358 m_State
[7] = 0x5BE0CD19UL
;
361 /*----------------------------------------------------------------------
362 | NPT_Sha256Digest::CompressBlock
363 +---------------------------------------------------------------------*/
365 NPT_Sha256Digest::CompressBlock(const NPT_UInt8
* block
)
367 NPT_UInt32 S
[8], W
[64];
369 // copy the state into the local workspace
370 for (unsigned int i
= 0; i
< 8; i
++) {
374 // copy the 512-bit block into W[0..15]
375 for (unsigned int i
= 0; i
< 16; i
++) {
376 W
[i
] = NPT_BytesToInt32Be(&block
[4*i
]);
380 for (unsigned int i
= 16; i
< 64; i
++) {
381 W
[i
] = NPT_Sha256_Gamma1(W
[i
- 2]) + W
[i
- 7] + NPT_Sha256_Gamma0(W
[i
- 15]) + W
[i
- 16];
385 for (unsigned int i
= 0; i
< 64; ++i
) {
388 NPT_Sha256_Sigma1(S
[4]) +
389 NPT_Sha256_Ch(S
[4], S
[5], S
[6]) +
392 NPT_UInt32 t1
= NPT_Sha256_Sigma0(S
[0]) + NPT_Sha256_Maj(S
[0], S
[1], S
[2]);
396 NPT_UInt32 t
= S
[7]; S
[7] = S
[6]; S
[6] = S
[5]; S
[5] = S
[4];
397 S
[4] = S
[3]; S
[3] = S
[2]; S
[2] = S
[1]; S
[1] = S
[0]; S
[0] = t
;
400 // store the local variables back into the state
401 for (unsigned i
= 0; i
< 8; i
++) {
406 /*----------------------------------------------------------------------
407 | NPT_Sha256Digest::GetDigest
408 +---------------------------------------------------------------------*/
410 NPT_Sha256Digest::GetDigest(NPT_DataBuffer
& digest
)
412 return ComputeDigest(m_State
, 8, true, digest
);
415 /*----------------------------------------------------------------------
417 +---------------------------------------------------------------------*/
418 class NPT_Md5Digest
: public NPT_BasicDigest
423 // NPT_Digest methods
424 virtual NPT_Result
GetDigest(NPT_DataBuffer
& digest
);
425 virtual unsigned int GetSize() { return 16; }
429 virtual void CompressBlock(const NPT_UInt8
* block
);
432 NPT_UInt32 m_State
[4];
435 /*----------------------------------------------------------------------
436 | NPT_Md5Digest::NPT_Md5Digest
437 +---------------------------------------------------------------------*/
438 NPT_Md5Digest::NPT_Md5Digest()
440 m_State
[0] = 0x67452301UL
;
441 m_State
[1] = 0xefcdab89UL
;
442 m_State
[2] = 0x98badcfeUL
;
443 m_State
[3] = 0x10325476UL
;
446 /*----------------------------------------------------------------------
447 | NPT_Md5Digest::CompressBlock
448 +---------------------------------------------------------------------*/
450 NPT_Md5Digest::CompressBlock(const NPT_UInt8
* block
)
452 NPT_UInt32 a
,b
,c
,d
,W
[16];
454 // copy the 512-bit block into W[0..15]
456 for (i
= 0; i
< 16; i
++) {
457 W
[i
] = NPT_BytesToInt32Le(&block
[4*i
]);
460 // copy the state to local variables
467 NPT_Md5_FF(a
,b
,c
,d
,W
[ 0], 7,0xd76aa478UL
)
468 NPT_Md5_FF(d
,a
,b
,c
,W
[ 1],12,0xe8c7b756UL
)
469 NPT_Md5_FF(c
,d
,a
,b
,W
[ 2],17,0x242070dbUL
)
470 NPT_Md5_FF(b
,c
,d
,a
,W
[ 3],22,0xc1bdceeeUL
)
471 NPT_Md5_FF(a
,b
,c
,d
,W
[ 4], 7,0xf57c0fafUL
)
472 NPT_Md5_FF(d
,a
,b
,c
,W
[ 5],12,0x4787c62aUL
)
473 NPT_Md5_FF(c
,d
,a
,b
,W
[ 6],17,0xa8304613UL
)
474 NPT_Md5_FF(b
,c
,d
,a
,W
[ 7],22,0xfd469501UL
)
475 NPT_Md5_FF(a
,b
,c
,d
,W
[ 8], 7,0x698098d8UL
)
476 NPT_Md5_FF(d
,a
,b
,c
,W
[ 9],12,0x8b44f7afUL
)
477 NPT_Md5_FF(c
,d
,a
,b
,W
[10],17,0xffff5bb1UL
)
478 NPT_Md5_FF(b
,c
,d
,a
,W
[11],22,0x895cd7beUL
)
479 NPT_Md5_FF(a
,b
,c
,d
,W
[12], 7,0x6b901122UL
)
480 NPT_Md5_FF(d
,a
,b
,c
,W
[13],12,0xfd987193UL
)
481 NPT_Md5_FF(c
,d
,a
,b
,W
[14],17,0xa679438eUL
)
482 NPT_Md5_FF(b
,c
,d
,a
,W
[15],22,0x49b40821UL
)
485 NPT_Md5_GG(a
,b
,c
,d
,W
[ 1], 5,0xf61e2562UL
)
486 NPT_Md5_GG(d
,a
,b
,c
,W
[ 6], 9,0xc040b340UL
)
487 NPT_Md5_GG(c
,d
,a
,b
,W
[11],14,0x265e5a51UL
)
488 NPT_Md5_GG(b
,c
,d
,a
,W
[ 0],20,0xe9b6c7aaUL
)
489 NPT_Md5_GG(a
,b
,c
,d
,W
[ 5], 5,0xd62f105dUL
)
490 NPT_Md5_GG(d
,a
,b
,c
,W
[10], 9,0x02441453UL
)
491 NPT_Md5_GG(c
,d
,a
,b
,W
[15],14,0xd8a1e681UL
)
492 NPT_Md5_GG(b
,c
,d
,a
,W
[ 4],20,0xe7d3fbc8UL
)
493 NPT_Md5_GG(a
,b
,c
,d
,W
[ 9], 5,0x21e1cde6UL
)
494 NPT_Md5_GG(d
,a
,b
,c
,W
[14], 9,0xc33707d6UL
)
495 NPT_Md5_GG(c
,d
,a
,b
,W
[ 3],14,0xf4d50d87UL
)
496 NPT_Md5_GG(b
,c
,d
,a
,W
[ 8],20,0x455a14edUL
)
497 NPT_Md5_GG(a
,b
,c
,d
,W
[13], 5,0xa9e3e905UL
)
498 NPT_Md5_GG(d
,a
,b
,c
,W
[ 2], 9,0xfcefa3f8UL
)
499 NPT_Md5_GG(c
,d
,a
,b
,W
[ 7],14,0x676f02d9UL
)
500 NPT_Md5_GG(b
,c
,d
,a
,W
[12],20,0x8d2a4c8aUL
)
503 NPT_Md5_HH(a
,b
,c
,d
,W
[ 5], 4,0xfffa3942UL
)
504 NPT_Md5_HH(d
,a
,b
,c
,W
[ 8],11,0x8771f681UL
)
505 NPT_Md5_HH(c
,d
,a
,b
,W
[11],16,0x6d9d6122UL
)
506 NPT_Md5_HH(b
,c
,d
,a
,W
[14],23,0xfde5380cUL
)
507 NPT_Md5_HH(a
,b
,c
,d
,W
[ 1], 4,0xa4beea44UL
)
508 NPT_Md5_HH(d
,a
,b
,c
,W
[ 4],11,0x4bdecfa9UL
)
509 NPT_Md5_HH(c
,d
,a
,b
,W
[ 7],16,0xf6bb4b60UL
)
510 NPT_Md5_HH(b
,c
,d
,a
,W
[10],23,0xbebfbc70UL
)
511 NPT_Md5_HH(a
,b
,c
,d
,W
[13], 4,0x289b7ec6UL
)
512 NPT_Md5_HH(d
,a
,b
,c
,W
[ 0],11,0xeaa127faUL
)
513 NPT_Md5_HH(c
,d
,a
,b
,W
[ 3],16,0xd4ef3085UL
)
514 NPT_Md5_HH(b
,c
,d
,a
,W
[ 6],23,0x04881d05UL
)
515 NPT_Md5_HH(a
,b
,c
,d
,W
[ 9], 4,0xd9d4d039UL
)
516 NPT_Md5_HH(d
,a
,b
,c
,W
[12],11,0xe6db99e5UL
)
517 NPT_Md5_HH(c
,d
,a
,b
,W
[15],16,0x1fa27cf8UL
)
518 NPT_Md5_HH(b
,c
,d
,a
,W
[ 2],23,0xc4ac5665UL
)
521 NPT_Md5_II(a
,b
,c
,d
,W
[ 0], 6,0xf4292244UL
)
522 NPT_Md5_II(d
,a
,b
,c
,W
[ 7],10,0x432aff97UL
)
523 NPT_Md5_II(c
,d
,a
,b
,W
[14],15,0xab9423a7UL
)
524 NPT_Md5_II(b
,c
,d
,a
,W
[ 5],21,0xfc93a039UL
)
525 NPT_Md5_II(a
,b
,c
,d
,W
[12], 6,0x655b59c3UL
)
526 NPT_Md5_II(d
,a
,b
,c
,W
[ 3],10,0x8f0ccc92UL
)
527 NPT_Md5_II(c
,d
,a
,b
,W
[10],15,0xffeff47dUL
)
528 NPT_Md5_II(b
,c
,d
,a
,W
[ 1],21,0x85845dd1UL
)
529 NPT_Md5_II(a
,b
,c
,d
,W
[ 8], 6,0x6fa87e4fUL
)
530 NPT_Md5_II(d
,a
,b
,c
,W
[15],10,0xfe2ce6e0UL
)
531 NPT_Md5_II(c
,d
,a
,b
,W
[ 6],15,0xa3014314UL
)
532 NPT_Md5_II(b
,c
,d
,a
,W
[13],21,0x4e0811a1UL
)
533 NPT_Md5_II(a
,b
,c
,d
,W
[ 4], 6,0xf7537e82UL
)
534 NPT_Md5_II(d
,a
,b
,c
,W
[11],10,0xbd3af235UL
)
535 NPT_Md5_II(c
,d
,a
,b
,W
[ 2],15,0x2ad7d2bbUL
)
536 NPT_Md5_II(b
,c
,d
,a
,W
[ 9],21,0xeb86d391UL
)
538 // store the variables back into the state
545 /*----------------------------------------------------------------------
546 | NPT_Md5Digest::GetDigest
547 +---------------------------------------------------------------------*/
549 NPT_Md5Digest::GetDigest(NPT_DataBuffer
& digest
)
551 return ComputeDigest(m_State
, 4, false, digest
);
554 /*----------------------------------------------------------------------
557 | compute Digest(key XOR opad, Digest(key XOR ipad, data))
559 | ipad is the byte 0x36 repeated 64 times
560 | opad is the byte 0x5c repeated 64 times
561 | and data is the data to authenticate
563 +---------------------------------------------------------------------*/
564 class NPT_HmacDigest
: public NPT_Digest
567 NPT_HmacDigest(NPT_Digest::Algorithm algorithm
,
568 const NPT_UInt8
* key
,
572 // NPT_Digest methods
573 virtual NPT_Result
Update(const NPT_UInt8
* data
, NPT_Size data_size
) {
574 return m_InnerDigest
->Update(data
, data_size
);
576 virtual NPT_Result
GetDigest(NPT_DataBuffer
& buffer
);
577 virtual unsigned int GetSize() { return m_InnerDigest
->GetSize(); }
580 NPT_Digest
* m_InnerDigest
;
581 NPT_Digest
* m_OuterDigest
;
584 /*----------------------------------------------------------------------
585 | NPT_HmacDigest::NPT_HmacDigest
586 +---------------------------------------------------------------------*/
587 NPT_HmacDigest::NPT_HmacDigest(NPT_Digest::Algorithm algorithm
,
588 const NPT_UInt8
* key
,
591 NPT_Digest::Create(algorithm
, m_InnerDigest
);
592 NPT_Digest::Create(algorithm
, m_OuterDigest
);
594 NPT_UInt8 workspace
[NPT_BASIC_DIGEST_BLOCK_SIZE
];
596 // if the key is larger than the block size, use a digest of the key
598 if (key_size
> NPT_BASIC_DIGEST_BLOCK_SIZE
) {
599 NPT_Digest
* key_digest
= NULL
;
600 NPT_Digest::Create(algorithm
, key_digest
);
601 key_digest
->Update(key
, key_size
);
602 key_digest
->GetDigest(hk
);
604 key_size
= hk
.GetDataSize();
608 // compute key XOR ipad
609 for (unsigned int i
= 0; i
< key_size
; i
++) {
610 workspace
[i
] = key
[i
] ^ 0x36;
612 for (unsigned int i
= key_size
; i
< NPT_BASIC_DIGEST_BLOCK_SIZE
; i
++) {
616 // start the inner digest with (key XOR ipad)
617 m_InnerDigest
->Update(workspace
, NPT_BASIC_DIGEST_BLOCK_SIZE
);
619 // compute key XOR opad
620 for (unsigned int i
= 0; i
< key_size
; i
++) {
621 workspace
[i
] = key
[i
] ^ 0x5c;
623 for (unsigned int i
= key_size
; i
< NPT_BASIC_DIGEST_BLOCK_SIZE
; i
++) {
627 // start the outer digest with (key XOR opad)
628 m_OuterDigest
->Update(workspace
, NPT_BASIC_DIGEST_BLOCK_SIZE
);
631 /*----------------------------------------------------------------------
632 | NPT_HmacDigest::~NPT_HmacDigest
633 +---------------------------------------------------------------------*/
634 NPT_HmacDigest::~NPT_HmacDigest()
636 delete m_InnerDigest
;
637 delete m_OuterDigest
;
640 /*----------------------------------------------------------------------
641 | NPT_HmacDigest::GetDigest
642 +---------------------------------------------------------------------*/
644 NPT_HmacDigest::GetDigest(NPT_DataBuffer
& mac
)
646 // finish the outer digest with the value of the inner digest
647 NPT_DataBuffer inner
;
648 m_InnerDigest
->GetDigest(inner
);
649 m_OuterDigest
->Update(inner
.GetData(), inner
.GetDataSize());
651 // return the value of the outer digest
652 return m_OuterDigest
->GetDigest(mac
);
655 /*----------------------------------------------------------------------
657 +---------------------------------------------------------------------*/
659 NPT_Digest::Create(Algorithm algorithm
, NPT_Digest
*& digest
)
662 case ALGORITHM_SHA1
: digest
= new NPT_Sha1Digest(); return NPT_SUCCESS
;
663 case ALGORITHM_SHA256
: digest
= new NPT_Sha256Digest(); return NPT_SUCCESS
;
664 case ALGORITHM_MD5
: digest
= new NPT_Md5Digest(); return NPT_SUCCESS
;
665 default: return NPT_ERROR_NOT_SUPPORTED
;
669 /*----------------------------------------------------------------------
671 +---------------------------------------------------------------------*/
673 NPT_Hmac::Create(NPT_Digest::Algorithm algorithm
,
674 const NPT_UInt8
* key
,
679 case NPT_Digest::ALGORITHM_SHA1
:
680 case NPT_Digest::ALGORITHM_MD5
:
681 digest
= new NPT_HmacDigest(algorithm
, key
, key_size
);
683 default: return NPT_ERROR_NOT_SUPPORTED
;