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 md4.c 15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Submitted by Dobes Vandermeer (dobes@smartt.com) 16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef MD4 19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_hash_descriptor md4_desc = 21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project "md4", 23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 6, 24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 16, 25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 64, 26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* OID */ 28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 1, 2, 840, 113549, 2, 4, }, 29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 6, 30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &md4_init, 32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &md4_process, 33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &md4_done, 34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &md4_test, 35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project NULL 36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}; 37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S11 3 39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S12 7 40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S13 11 41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S14 19 42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S21 3 43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S22 5 44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S23 9 45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S24 13 46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S31 3 47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S32 9 48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S33 11 49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define S34 15 50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* F, G and H are basic MD4 functions. */ 52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define F(x, y, z) (z ^ (x & (y ^ z))) 53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define G(x, y, z) ((x & y) | (z & (x | y))) 54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define H(x, y, z) ((x) ^ (y) ^ (z)) 55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* ROTATE_LEFT rotates x left n bits. */ 57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ROTATE_LEFT(x, n) ROLc(x, n) 58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ 60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Rotation is separate from addition to prevent recomputation */ 61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define FF(a, b, c, d, x, s) { \ 63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (a) += F ((b), (c), (d)) + (x); \ 64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (a) = ROTATE_LEFT ((a), (s)); \ 65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define GG(a, b, c, d, x, s) { \ 67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \ 68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (a) = ROTATE_LEFT ((a), (s)); \ 69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define HH(a, b, c, d, x, s) { \ 71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \ 72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (a) = ROTATE_LEFT ((a), (s)); \ 73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK 76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int _md4_compress(hash_state *md, unsigned char *buf) 77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else 78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int md4_compress(hash_state *md, unsigned char *buf) 79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 x[16], a, b, c, d; 82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* copy state */ 85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project a = md->md4.state[0]; 86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project b = md->md4.state[1]; 87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c = md->md4.state[2]; 88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project d = md->md4.state[3]; 89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* copy the state into 512-bits into W[0..15] */ 91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < 16; i++) { 92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LOAD32L(x[i], buf + (4*i)); 93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Round 1 */ 96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (a, b, c, d, x[ 0], S11); /* 1 */ 97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (d, a, b, c, x[ 1], S12); /* 2 */ 98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (c, d, a, b, x[ 2], S13); /* 3 */ 99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (b, c, d, a, x[ 3], S14); /* 4 */ 100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (a, b, c, d, x[ 4], S11); /* 5 */ 101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (d, a, b, c, x[ 5], S12); /* 6 */ 102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (c, d, a, b, x[ 6], S13); /* 7 */ 103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (b, c, d, a, x[ 7], S14); /* 8 */ 104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (a, b, c, d, x[ 8], S11); /* 9 */ 105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (d, a, b, c, x[ 9], S12); /* 10 */ 106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (c, d, a, b, x[10], S13); /* 11 */ 107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (b, c, d, a, x[11], S14); /* 12 */ 108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (a, b, c, d, x[12], S11); /* 13 */ 109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (d, a, b, c, x[13], S12); /* 14 */ 110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (c, d, a, b, x[14], S13); /* 15 */ 111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project FF (b, c, d, a, x[15], S14); /* 16 */ 112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Round 2 */ 114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (a, b, c, d, x[ 0], S21); /* 17 */ 115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (d, a, b, c, x[ 4], S22); /* 18 */ 116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (c, d, a, b, x[ 8], S23); /* 19 */ 117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (b, c, d, a, x[12], S24); /* 20 */ 118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (a, b, c, d, x[ 1], S21); /* 21 */ 119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (d, a, b, c, x[ 5], S22); /* 22 */ 120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (c, d, a, b, x[ 9], S23); /* 23 */ 121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (b, c, d, a, x[13], S24); /* 24 */ 122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (a, b, c, d, x[ 2], S21); /* 25 */ 123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (d, a, b, c, x[ 6], S22); /* 26 */ 124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (c, d, a, b, x[10], S23); /* 27 */ 125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (b, c, d, a, x[14], S24); /* 28 */ 126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (a, b, c, d, x[ 3], S21); /* 29 */ 127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (d, a, b, c, x[ 7], S22); /* 30 */ 128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (c, d, a, b, x[11], S23); /* 31 */ 129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project GG (b, c, d, a, x[15], S24); /* 32 */ 130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Round 3 */ 132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (a, b, c, d, x[ 0], S31); /* 33 */ 133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (d, a, b, c, x[ 8], S32); /* 34 */ 134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (c, d, a, b, x[ 4], S33); /* 35 */ 135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (b, c, d, a, x[12], S34); /* 36 */ 136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (a, b, c, d, x[ 2], S31); /* 37 */ 137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (d, a, b, c, x[10], S32); /* 38 */ 138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (c, d, a, b, x[ 6], S33); /* 39 */ 139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (b, c, d, a, x[14], S34); /* 40 */ 140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (a, b, c, d, x[ 1], S31); /* 41 */ 141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (d, a, b, c, x[ 9], S32); /* 42 */ 142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (c, d, a, b, x[ 5], S33); /* 43 */ 143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (b, c, d, a, x[13], S34); /* 44 */ 144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (a, b, c, d, x[ 3], S31); /* 45 */ 145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (d, a, b, c, x[11], S32); /* 46 */ 146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (c, d, a, b, x[ 7], S33); /* 47 */ 147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HH (b, c, d, a, x[15], S34); /* 48 */ 148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Update our state */ 151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[0] = md->md4.state[0] + a; 152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[1] = md->md4.state[1] + b; 153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[2] = md->md4.state[2] + c; 154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[3] = md->md4.state[3] + d; 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#ifdef LTC_CLEAN_STACK 160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int md4_compress(hash_state *md, unsigned char *buf) 161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int err; 163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project err = _md4_compress(md, buf); 164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project burn_stack(sizeof(ulong32) * 20 + sizeof(int)); 165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Initialize the hash state 171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param md The hash state you wish to initialize 172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint md4_init(hash_state * md) 175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(md != NULL); 177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[0] = 0x67452301UL; 178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[1] = 0xefcdab89UL; 179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[2] = 0x98badcfeUL; 180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.state[3] = 0x10325476UL; 181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.length = 0; 182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.curlen = 0; 183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Process a block of memory though the hash 188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param md The hash state 189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param in The data to hash 190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param inlen The length of the data (octets) 191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectHASH_PROCESS(md4_process, md4_compress, md4, 64) 194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Terminate the hash to get the digest 197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param md The hash state 198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param out [out] The destination of the hash (16 bytes) 199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint md4_done(hash_state * md, unsigned char *out) 202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(md != NULL); 206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(out != NULL); 207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (md->md4.curlen >= sizeof(md->md4.buf)) { 209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_ARG; 210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* increase the length of the message */ 213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.length += md->md4.curlen * 8; 214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* append the '1' bit */ 216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.buf[md->md4.curlen++] = (unsigned char)0x80; 217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* if the length is currently above 56 bytes we append zeros 219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * then compress. Then we can fall back to padding zeros and length 220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * encoding like normal. 221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (md->md4.curlen > 56) { 223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project while (md->md4.curlen < 64) { 224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.buf[md->md4.curlen++] = (unsigned char)0; 225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md4_compress(md, md->md4.buf); 227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.curlen = 0; 228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* pad upto 56 bytes of zeroes */ 231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project while (md->md4.curlen < 56) { 232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md->md4.buf[md->md4.curlen++] = (unsigned char)0; 233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* store length */ 236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STORE64L(md->md4.length, md->md4.buf+56); 237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md4_compress(md, md->md4.buf); 238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* copy output */ 240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < 4; i++) { 241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STORE32L(md->md4.state[i], out+(4*i)); 242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK 244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project zeromem(md, sizeof(hash_state)); 245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Self-test the hash 251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled 252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint md4_test(void) 254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #ifndef LTC_TEST 256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_NOP; 257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #else 258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const struct md4_test_case { 259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project char *input; 260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char digest[16]; 261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } cases[] = { 262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { "", 263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} }, 265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { "a", 266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, 267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} }, 268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { "abc", 269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, 270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} }, 271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { "message digest", 272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, 273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} }, 274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { "abcdefghijklmnopqrstuvwxyz", 275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, 276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} }, 277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, 279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} }, 280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} }, 283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project }; 284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project hash_state md; 286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char digest[16]; 287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { 289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md4_init(&md); 290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input)); 291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project md4_done(&md, digest); 292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (XMEMCMP(digest, cases[i].digest, 16) != 0) { 293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_FAIL_TESTVECTOR; 294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #endif 299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md4.c,v $ */ 306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.8 $ */ 307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/01 09:28:17 $ */ 308