Mercurial > dropbear
view sha1-asm-ltc.c @ 910:89555751c489 asm
merge up to 2013.63, improve ASM makefile rules a bit
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 27 Feb 2014 21:35:58 +0800 |
parents | e4b75744acab |
children |
line wrap: on
line source
/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, [email protected], http://libtomcrypt.com */ #include "tomcrypt.h" /** @file sha1.c SHA1 code by Tom St Denis */ #ifdef DROPBEAR_SHA1_ASM /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ static int sha1_asm_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->sha1.state[0] = 0x67452301UL; md->sha1.state[1] = 0xefcdab89UL; md->sha1.state[2] = 0x98badcfeUL; md->sha1.state[3] = 0x10325476UL; md->sha1.state[4] = 0xc3d2e1f0UL; md->sha1.curlen = 0; md->sha1.length = 0; return CRYPT_OK; } void sha1_block_data_order(void* sha1s, const unsigned char *buf, size_t num); static int sha1_asm_compress(hash_state *md, unsigned char *buf, size_t num) { sha1_block_data_order(&md->sha1.state, buf, num); return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ int sha1_asm_process (hash_state * md, const unsigned char *in, unsigned long inlen) \ { \ unsigned long n; \ int err; \ LTC_ARGCHK(md != NULL); \ LTC_ARGCHK(in != NULL); \ if (md-> sha1 .curlen > sizeof(md-> sha1 .buf)) { \ return CRYPT_INVALID_ARG; \ } \ while (inlen > 0) { \ if (md-> sha1 .curlen == 0 && inlen >= 64) { \ //const size_t num = inlen / 64; const size_t num = 1; if ((err = sha1_asm_compress (md, (unsigned char *)in, num)) != CRYPT_OK) { \ return err; \ } \ md-> sha1 .length += 64 * 8 * num; \ in += 64 * num; \ inlen -= 64 * num; \ } else { \ n = MIN(inlen, (64 - md-> sha1 .curlen)); \ memcpy(md-> sha1 .buf + md-> sha1.curlen, in, (size_t)n); \ md-> sha1 .curlen += n; \ in += n; \ inlen -= n; \ if (md-> sha1 .curlen == 64) { \ if ((err = sha1_asm_compress (md, md-> sha1 .buf, 1)) != CRYPT_OK) { \ return err; \ } \ md-> sha1 .length += 8*64; \ md-> sha1 .curlen = 0; \ } \ } \ } \ return CRYPT_OK; \ } /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int sha1_asm_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->sha1.curlen >= sizeof(md->sha1.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->sha1.length += md->sha1.curlen * 8; /* append the '1' bit */ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->sha1.curlen > 56) { while (md->sha1.curlen < 64) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } sha1_asm_compress(md, md->sha1.buf, 1); md->sha1.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->sha1.curlen < 56) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } /* store length */ STORE64H(md->sha1.length, md->sha1.buf+56); sha1_asm_compress(md, md->sha1.buf, 1); /* copy output */ for (i = 0; i < 5; i++) { STORE32H(md->sha1.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha1_asm_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[20]; } tests[] = { { "abc", { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } } }; int i; unsigned char tmp[20]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha1_init(&md); sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha1_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } const struct ltc_hash_descriptor sha1_asm_desc = { "sha1_asm", 102, 20, 64, /* OID */ { 1, 3, 14, 3, 2, 26, }, 6, &sha1_asm_init, &sha1_asm_process, &sha1_asm_done, &sha1_asm_test, NULL }; #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/11/01 09:28:17 $ */