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   @param sha512.c
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   SHA512 by Tom St Denis
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef SHA512
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_hash_descriptor sha512_desc =
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    "sha512",
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    5,
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    64,
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    128,
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* OID */
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   { 2, 16, 840, 1, 101, 3, 4, 2, 3,  },
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   9,
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha512_init,
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha512_process,
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha512_done,
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &sha512_test,
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    NULL
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* the K array */
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic const ulong64 K[80] = {
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectCONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Various logical functions */
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define Maj(x,y,z)      (((x | y) & z) | (x & y))
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S(x, n)         ROR64c(x, n)
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define R(x, n)         (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* compress 1024-bits */
93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int _sha512_compress(hash_state * md, unsigned char *buf)
95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int  sha512_compress(hash_state * md, unsigned char *buf)
97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    ulong64 S[8], W[80], t0, t1;
100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    int i;
101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy state into S */
103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 8; i++) {
104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[i] = md->sha512.state[i];
105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy the state into 1024-bits into W[0..15] */
108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 16; i++) {
109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD64H(W[i], buf + (8*i));
110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* fill W[16..79] */
113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 16; i < 80; i++) {
114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* Compress */
118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_SMALL_CODE
119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 80; i++) {
120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[7] = S[6];
123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[6] = S[5];
124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[5] = S[4];
125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[4] = S[3] + t0;
126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[3] = S[2];
127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[2] = S[1];
128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[1] = S[0];
129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        S[0] = t0 + t1;
130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define RND(a,b,c,d,e,f,g,h,i)                    \
133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     t1 = Sigma0(a) + Maj(a, b, c);                  \
135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     d += t0;                                        \
136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     h  = t0 + t1;
137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     for (i = 0; i < 80; i += 8) {
139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     }
148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* feedback */
152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 8; i++) {
153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        md->sha512.state[i] = md->sha512.state[i] + S[i];
154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* compress 1024-bits */
160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int sha512_compress(hash_state * md, unsigned char *buf)
162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    int err;
164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    err = _sha512_compress(md, buf);
165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    burn_stack(sizeof(ulong64) * 90 + sizeof(int));
166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return err;
167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   Initialize the hash state
172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param md   The hash state you wish to initialize
173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @return CRYPT_OK if successful
174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sha512_init(hash_state * md)
176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(md != NULL);
178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.curlen = 0;
179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.length = 0;
180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[4] = CONST64(0x510e527fade682d1);
185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   Process a block of memory though the hash
193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param md     The hash state
194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param in     The data to hash
195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param inlen  The length of the data (octets)
196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @return CRYPT_OK if successful
197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectHASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   Terminate the hash to get the digest
202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param md  The hash state
203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param out [out] The destination of the hash (64 bytes)
204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @return CRYPT_OK if successful
205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sha512_done(hash_state * md, unsigned char *out)
207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    int i;
209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(md  != NULL);
211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(out != NULL);
212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return CRYPT_INVALID_ARG;
215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* increase the length of the message */
218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.length += md->sha512.curlen * CONST64(8);
219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* append the '1' bit */
221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* if the length is currently above 112 bytes we append zeros
224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * then compress.  Then we can fall back to padding zeros and length
225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * encoding like normal.
226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (md->sha512.curlen > 112) {
228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        while (md->sha512.curlen < 128) {
229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        sha512_compress(md, md->sha512.buf);
232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        md->sha512.curlen = 0;
233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* pad upto 120 bytes of zeroes
236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * note: that from 112 to 120 is the 64 MSB of the length.  We assume that you won't hash
237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * > 2^64 bits of data... :-)
238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    while (md->sha512.curlen < 120) {
240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* store length */
244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE64H(md->sha512.length, md->sha512.buf+120);
245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    sha512_compress(md, md->sha512.buf);
246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy output */
248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 0; i < 8; i++) {
249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        STORE64H(md->sha512.state[i], out+(8*i));
250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    zeromem(md, sizeof(hash_state));
253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Self-test the hash
259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint  sha512_test(void)
262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #ifndef LTC_TEST
264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_NOP;
265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #else
266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  static const struct {
267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      char *msg;
268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      unsigned char hash[64];
269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  } tests[] = {
270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    { "abc",
271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    },
280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    },
290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  };
291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  int i;
293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  unsigned char tmp[64];
294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  hash_state md;
295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      sha512_init(&md);
298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      sha512_done(&md, tmp);
300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      if (XMEMCMP(tmp, tests[i].hash, 64) != 0) {
301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project         return CRYPT_FAIL_TESTVECTOR;
302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      }
303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  return CRYPT_OK;
305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  #endif
306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
308f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef SHA384
309f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   #include "sha384.c"
310f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
311f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
312f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
313f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
314f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
315f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
316f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
317f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha512.c,v $ */
318f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.8 $ */
319f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/01 09:28:17 $ */
320