arm / sha1.con commit block-sha1: guard gcc extensions with __GNUC__ (e9c5dcd)
   1/*
   2 * SHA-1 implementation optimized for ARM
   3 *
   4 * Copyright:   (C) 2005 by Nicolas Pitre <nico@cam.org>
   5 * Created:     September 17, 2005
   6 */
   7
   8#include <string.h>
   9#include "sha1.h"
  10
  11extern void arm_sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
  12
  13void arm_SHA1_Init(arm_SHA_CTX *c)
  14{
  15        c->len = 0;
  16        c->hash[0] = 0x67452301;
  17        c->hash[1] = 0xefcdab89;
  18        c->hash[2] = 0x98badcfe;
  19        c->hash[3] = 0x10325476;
  20        c->hash[4] = 0xc3d2e1f0;
  21}
  22
  23void arm_SHA1_Update(arm_SHA_CTX *c, const void *p, unsigned long n)
  24{
  25        uint32_t workspace[80];
  26        unsigned int partial;
  27        unsigned long done;
  28
  29        partial = c->len & 0x3f;
  30        c->len += n;
  31        if ((partial + n) >= 64) {
  32                if (partial) {
  33                        done = 64 - partial;
  34                        memcpy(c->buffer + partial, p, done);
  35                        arm_sha_transform(c->hash, c->buffer, workspace);
  36                        partial = 0;
  37                } else
  38                        done = 0;
  39                while (n >= done + 64) {
  40                        arm_sha_transform(c->hash, p + done, workspace);
  41                        done += 64;
  42                }
  43        } else
  44                done = 0;
  45        if (n - done)
  46                memcpy(c->buffer + partial, p + done, n - done);
  47}
  48
  49void arm_SHA1_Final(unsigned char *hash, arm_SHA_CTX *c)
  50{
  51        uint64_t bitlen;
  52        uint32_t bitlen_hi, bitlen_lo;
  53        unsigned int i, offset, padlen;
  54        unsigned char bits[8];
  55        static const unsigned char padding[64] = { 0x80, };
  56
  57        bitlen = c->len << 3;
  58        offset = c->len & 0x3f;
  59        padlen = ((offset < 56) ? 56 : (64 + 56)) - offset;
  60        arm_SHA1_Update(c, padding, padlen);
  61
  62        bitlen_hi = bitlen >> 32;
  63        bitlen_lo = bitlen & 0xffffffff;
  64        bits[0] = bitlen_hi >> 24;
  65        bits[1] = bitlen_hi >> 16;
  66        bits[2] = bitlen_hi >> 8;
  67        bits[3] = bitlen_hi;
  68        bits[4] = bitlen_lo >> 24;
  69        bits[5] = bitlen_lo >> 16;
  70        bits[6] = bitlen_lo >> 8;
  71        bits[7] = bitlen_lo;
  72        arm_SHA1_Update(c, bits, 8);
  73
  74        for (i = 0; i < 5; i++) {
  75                uint32_t v = c->hash[i];
  76                hash[0] = v >> 24;
  77                hash[1] = v >> 16;
  78                hash[2] = v >> 8;
  79                hash[3] = v;
  80                hash += 4;
  81        }
  82}