1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LibTomCrypt is a library that provides various cryptographic
4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algorithms in a highly modular and flexible manner.
5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library is free for all purposes without any express
7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * guarantee it works.
8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "tomcrypt.h"
12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @file sha1.c
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  SHA1 code by Tom St Denis
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef SHA1
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_hash_descriptor sha1_desc =
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    "sha1",
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    2,
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    20,
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    64,
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* OID */
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   { 1, 3, 14, 3, 2, 26,  },
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   6,
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha1_init,
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha1_process,
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha1_done,
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha1_test,
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    NULL
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define F0(x,y,z)  (z ^ (x & (y ^ z)))
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define F1(x,y,z)  (x ^ y ^ z)
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define F2(x,y,z)  ((x & y) | (z & (x | y)))
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define F3(x,y,z)  (x ^ y ^ z)
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int _sha1_compress(hash_state *md, unsigned char *buf)
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int  sha1_compress(hash_state *md, unsigned char *buf)
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    ulong32 a,b,c,d,e,W[80],i;
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_SMALL_CODE
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    ulong32 t;
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy the state into 512-bits into W[0..15] */
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 16; i++) {
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD32H(W[i], buf + (4*i));
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy state */
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    a = md->sha1.state[0];
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    b = md->sha1.state[1];
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    c = md->sha1.state[2];
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    d = md->sha1.state[3];
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    e = md->sha1.state[4];
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* expand it */
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 16; i < 80; i++) {
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* compress */
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* round one */
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_SMALL_CODE
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 20; ) {
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (; i < 40; ) {
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (; i < 60; ) {
90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (; i < 80; ) {
94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 20; ) {
100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF0(a,b,c,d,e,i++);
101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF0(e,a,b,c,d,i++);
102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF0(d,e,a,b,c,i++);
103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF0(c,d,e,a,b,i++);
104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF0(b,c,d,e,a,i++);
105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* round two */
108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (; i < 40; )  {
109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF1(a,b,c,d,e,i++);
110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF1(e,a,b,c,d,i++);
111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF1(d,e,a,b,c,i++);
112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF1(c,d,e,a,b,i++);
113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF1(b,c,d,e,a,i++);
114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* round three */
117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (; i < 60; )  {
118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF2(a,b,c,d,e,i++);
119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF2(e,a,b,c,d,i++);
120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF2(d,e,a,b,c,i++);
121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF2(c,d,e,a,b,i++);
122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF2(b,c,d,e,a,i++);
123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* round four */
126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (; i < 80; )  {
127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF3(a,b,c,d,e,i++);
128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF3(e,a,b,c,d,i++);
129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF3(d,e,a,b,c,i++);
130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF3(c,d,e,a,b,i++);
131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       FF3(b,c,d,e,a,i++);
132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #undef FF0
136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #undef FF1
137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #undef FF2
138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #undef FF3
139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* store */
141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha1.state[0] = md->sha1.state[0] + a;
142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha1.state[1] = md->sha1.state[1] + b;
143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha1.state[2] = md->sha1.state[2] + c;
144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha1.state[3] = md->sha1.state[3] + d;
145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha1.state[4] = md->sha1.state[4] + e;
146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int sha1_compress(hash_state *md, unsigned char *buf)
152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int err;
154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   err = _sha1_compress(md, buf);
155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   burn_stack(sizeof(ulong32) * 87);
156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return err;
157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   Initialize the hash state
162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param md   The hash state you wish to initialize
163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @return CRYPT_OK if successful
164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sha1_init(hash_state * md)
166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(md != NULL);
168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   md->sha1.state[0] = 0x67452301UL;
169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   md->sha1.state[1] = 0xefcdab89UL;
170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   md->sha1.state[2] = 0x98badcfeUL;
171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   md->sha1.state[3] = 0x10325476UL;
172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   md->sha1.state[4] = 0xc3d2e1f0UL;
173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   md->sha1.curlen = 0;
174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   md->sha1.length = 0;
175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return CRYPT_OK;
176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   Process a block of memory though the hash
180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param md     The hash state
181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param in     The data to hash
182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param inlen  The length of the data (octets)
183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @return CRYPT_OK if successful
184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectHASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   Terminate the hash to get the digest
189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param md  The hash state
190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param out [out] The destination of the hash (20 bytes)
191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @return CRYPT_OK if successful
192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sha1_done(hash_state * md, unsigned char *out)
194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    int i;
196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(md  != NULL);
198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(out != NULL);
199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return CRYPT_INVALID_ARG;
202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* increase the length of the message */
205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha1.length += md->sha1.curlen * 8;
206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* append the '1' bit */
208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* if the length is currently above 56 bytes we append zeros
211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * then compress.  Then we can fall back to padding zeros and length
212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * encoding like normal.
213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (md->sha1.curlen > 56) {
215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        while (md->sha1.curlen < 64) {
216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        sha1_compress(md, md->sha1.buf);
219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        md->sha1.curlen = 0;
220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* pad upto 56 bytes of zeroes */
223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    while (md->sha1.curlen < 56) {
224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* store length */
228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE64H(md->sha1.length, md->sha1.buf+56);
229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    sha1_compress(md, md->sha1.buf);
230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy output */
232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 5; i++) {
233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        STORE32H(md->sha1.state[i], out+(4*i));
234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    zeromem(md, sizeof(hash_state));
237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Self-test the hash
243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint  sha1_test(void)
246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #ifndef LTC_TEST
248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_NOP;
249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #else
250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  static const struct {
251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      char *msg;
252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      unsigned char hash[20];
253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  } tests[] = {
254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    { "abc",
255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x9c, 0xd0, 0xd8, 0x9d }
258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    },
259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0xE5, 0x46, 0x70, 0xF1 }
263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  };
265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  int i;
267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  unsigned char tmp[20];
268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  hash_state md;
269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0]));  i++) {
271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      sha1_init(&md);
272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      sha1_done(&md, tmp);
274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      if (XMEMCMP(tmp, tests[i].hash, 20) != 0) {
275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         return CRYPT_FAIL_TESTVECTOR;
276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      }
277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  return CRYPT_OK;
279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  #endif
280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */
287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.8 $ */
288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/01 09:28:17 $ */
289