-/* The SHA f()-functions. */
-
-#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
-#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
-#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
-#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
-
-/* The SHA Mysterious Constants */
-
-#define K1 0x5A827999L /* Rounds 0-19 */
-#define K2 0x6ED9EBA1L /* Rounds 20-39 */
-#define K3 0x8F1BBCDCL /* Rounds 40-59 */
-#define K4 0xCA62C1D6L /* Rounds 60-79 */
-
-#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
-
-#define expand(W,i) ( W[ i & 15 ] = \
- ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
- W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
-
-#define subRound(a, b, c, d, e, f, k, data) \
- ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
-
-
-void SHATransform(word32 *digest, word32 *data)
-{
- word32 A, B, C, D, E; /* Local vars */
- word32 eData[ 16 ]; /* Expanded data */
-
- /* Set up first buffer and local data buffer */
- A = digest[ 0 ];
- B = digest[ 1 ];
- C = digest[ 2 ];
- D = digest[ 3 ];
- E = digest[ 4 ];
- memcpy( eData, data, 16*sizeof(word32));
-
- /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
- subRound( A, B, C, D, E, f1, K1, eData[ 0 ] );
- subRound( E, A, B, C, D, f1, K1, eData[ 1 ] );
- subRound( D, E, A, B, C, f1, K1, eData[ 2 ] );
- subRound( C, D, E, A, B, f1, K1, eData[ 3 ] );
- subRound( B, C, D, E, A, f1, K1, eData[ 4 ] );
- subRound( A, B, C, D, E, f1, K1, eData[ 5 ] );
- subRound( E, A, B, C, D, f1, K1, eData[ 6 ] );
- subRound( D, E, A, B, C, f1, K1, eData[ 7 ] );
- subRound( C, D, E, A, B, f1, K1, eData[ 8 ] );
- subRound( B, C, D, E, A, f1, K1, eData[ 9 ] );
- subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
- subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
- subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
- subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
- subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
- subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
- subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
- subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
- subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
- subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
-
- subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
- subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
- subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
- subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
- subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
- subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
- subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
- subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
- subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
- subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
- subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
- subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
- subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
- subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
- subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
- subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
- subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
- subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
- subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
- subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
-
- subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
- subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
- subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
- subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
- subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
- subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
- subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
- subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
- subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
- subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
- subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
- subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
- subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
- subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
- subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
- subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
- subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
- subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
- subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
- subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
-
- subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
- subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
- subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
- subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
- subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
- subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
- subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
- subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
- subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
- subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
- subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
- subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
- subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
- subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
- subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
- subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
- subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
- subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
- subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
- subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
-
- /* Build message digest */
- digest[ 0 ] += A;
- digest[ 1 ] += B;
- digest[ 2 ] += C;
- digest[ 3 ] += D;
- digest[ 4 ] += E;
+static void *sha1_make_context(void)
+{
+ return snewn(3, SHA_State);
+}
+
+static void sha1_free_context(void *handle)
+{
+ sfree(handle);
+}
+
+static void sha1_key_internal(void *handle, unsigned char *key, int len)
+{
+ SHA_State *keys = (SHA_State *)handle;
+ unsigned char foo[64];
+ int i;
+
+ memset(foo, 0x36, 64);
+ for (i = 0; i < len && i < 64; i++)
+ foo[i] ^= key[i];
+ SHA_Init(&keys[0]);
+ SHA_Bytes(&keys[0], foo, 64);
+
+ memset(foo, 0x5C, 64);
+ for (i = 0; i < len && i < 64; i++)
+ foo[i] ^= key[i];
+ SHA_Init(&keys[1]);
+ SHA_Bytes(&keys[1], foo, 64);
+
+ smemclr(foo, 64); /* burn the evidence */
+}
+
+static void sha1_key(void *handle, unsigned char *key)
+{
+ sha1_key_internal(handle, key, 20);
+}
+
+static void sha1_key_buggy(void *handle, unsigned char *key)
+{
+ sha1_key_internal(handle, key, 16);
+}
+
+static void hmacsha1_start(void *handle)
+{
+ SHA_State *keys = (SHA_State *)handle;
+
+ keys[2] = keys[0]; /* structure copy */
+}
+
+static void hmacsha1_bytes(void *handle, unsigned char const *blk, int len)
+{
+ SHA_State *keys = (SHA_State *)handle;
+ SHA_Bytes(&keys[2], (void *)blk, len);
+}
+
+static void hmacsha1_genresult(void *handle, unsigned char *hmac)
+{
+ SHA_State *keys = (SHA_State *)handle;
+ SHA_State s;
+ unsigned char intermediate[20];
+
+ s = keys[2]; /* structure copy */
+ SHA_Final(&s, intermediate);
+ s = keys[1]; /* structure copy */
+ SHA_Bytes(&s, intermediate, 20);
+ SHA_Final(&s, hmac);
+}
+
+static void sha1_do_hmac(void *handle, unsigned char *blk, int len,
+ unsigned long seq, unsigned char *hmac)
+{
+ unsigned char seqbuf[4];
+
+ PUT_32BIT_MSB_FIRST(seqbuf, seq);
+ hmacsha1_start(handle);
+ hmacsha1_bytes(handle, seqbuf, 4);
+ hmacsha1_bytes(handle, blk, len);
+ hmacsha1_genresult(handle, hmac);
+}
+
+static void sha1_generate(void *handle, unsigned char *blk, int len,
+ unsigned long seq)
+{
+ sha1_do_hmac(handle, blk, len, seq, blk + len);
+}
+
+static int hmacsha1_verresult(void *handle, unsigned char const *hmac)
+{
+ unsigned char correct[20];
+ hmacsha1_genresult(handle, correct);
+ return !memcmp(correct, hmac, 20);
+}
+
+static int sha1_verify(void *handle, unsigned char *blk, int len,
+ unsigned long seq)
+{
+ unsigned char correct[20];
+ sha1_do_hmac(handle, blk, len, seq, correct);
+ return !memcmp(correct, blk + len, 20);
+}
+
+static void hmacsha1_96_genresult(void *handle, unsigned char *hmac)
+{
+ unsigned char full[20];
+ hmacsha1_genresult(handle, full);
+ memcpy(hmac, full, 12);
+}
+
+static void sha1_96_generate(void *handle, unsigned char *blk, int len,
+ unsigned long seq)
+{
+ unsigned char full[20];
+ sha1_do_hmac(handle, blk, len, seq, full);
+ memcpy(blk + len, full, 12);
+}
+
+static int hmacsha1_96_verresult(void *handle, unsigned char const *hmac)
+{
+ unsigned char correct[20];
+ hmacsha1_genresult(handle, correct);
+ return !memcmp(correct, hmac, 12);
+}
+
+static int sha1_96_verify(void *handle, unsigned char *blk, int len,
+ unsigned long seq)
+{
+ unsigned char correct[20];
+ sha1_do_hmac(handle, blk, len, seq, correct);
+ return !memcmp(correct, blk + len, 12);
+}
+
+void hmac_sha1_simple(void *key, int keylen, void *data, int datalen,
+ unsigned char *output) {
+ SHA_State states[2];
+ unsigned char intermediate[20];
+
+ sha1_key_internal(states, key, keylen);
+ SHA_Bytes(&states[0], data, datalen);
+ SHA_Final(&states[0], intermediate);
+
+ SHA_Bytes(&states[1], intermediate, 20);
+ SHA_Final(&states[1], output);