Annotation of embedaddon/strongswan/src/libstrongswan/plugins/sha1/sha1_hasher.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2005-2006 Martin Willi
                      3:  * Copyright (C) 2005 Jan Hutter
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * Ported from Steve Reid's <steve@edmweb.com> implementation
                      7:  * "SHA1 in C" found in strongSwan.
                      8:  *
                      9:  * This program is free software; you can redistribute it and/or modify it
                     10:  * under the terms of the GNU General Public License as published by the
                     11:  * Free Software Foundation; either version 2 of the License, or (at your
                     12:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     13:  *
                     14:  * This program is distributed in the hope that it will be useful, but
                     15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     16:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     17:  * for more details.
                     18:  */
                     19: 
                     20: #include <string.h>
                     21: 
                     22: #include <library.h>
                     23: 
                     24: #include "sha1_hasher.h"
                     25: 
                     26: /*
                     27:  * ugly macro stuff
                     28:  */
                     29: #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
                     30: 
                     31: #if BYTE_ORDER == LITTLE_ENDIAN
                     32:  #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) |(rol(block->l[i],8)&0x00FF00FF))
                     33: #elif BYTE_ORDER == BIG_ENDIAN
                     34:  #define blk0(i) block->l[i]
                     35: #else
                     36:  #error "Endianness not defined!"
                     37: #endif
                     38: #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] ^block->l[(i+2)&15]^block->l[i&15],1))
                     39: 
                     40: /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
                     41: #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
                     42: #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
                     43: #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
                     44: #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
                     45: #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
                     46: 
                     47: 
                     48: typedef struct private_sha1_hasher_t private_sha1_hasher_t;
                     49: 
                     50: /**
                     51:  * Private data structure with hashing context.
                     52:  */
                     53: struct private_sha1_hasher_t {
                     54:        /**
                     55:         * Public interface for this hasher.
                     56:         */
                     57:        sha1_hasher_t public;
                     58: 
                     59:        /*
                     60:         * State of the hasher. Shared with sha1_prf.c, do not change it!!!
                     61:         */
                     62:        uint32_t state[5];
                     63:        uint32_t count[2];
                     64:        uint8_t buffer[64];
                     65: };
                     66: 
                     67: /*
                     68:  * Hash a single 512-bit block. This is the core of the algorithm. *
                     69:  */
                     70: static void SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
                     71: {
                     72:        uint32_t a, b, c, d, e;
                     73:        typedef union {
                     74:                uint8_t c[64];
                     75:                uint32_t l[16];
                     76:        } CHAR64LONG16;
                     77:        CHAR64LONG16 block[1];  /* use array to appear as a pointer */
                     78:        memcpy(block, buffer, 64);
                     79: 
                     80:        /* Copy context->state[] to working vars */
                     81:        a = state[0];
                     82:        b = state[1];
                     83:        c = state[2];
                     84:        d = state[3];
                     85:        e = state[4];
                     86:        /* 4 rounds of 20 operations each. Loop unrolled. */
                     87:        R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
                     88:        R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
                     89:        R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
                     90:        R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
                     91:        R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
                     92:        R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
                     93:        R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
                     94:        R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
                     95:        R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
                     96:        R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
                     97:        R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
                     98:        R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
                     99:        R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
                    100:        R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
                    101:        R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
                    102:        R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
                    103:        R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
                    104:        R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
                    105:        R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
                    106:        R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
                    107:        /* Add the working vars back into context.state[] */
                    108:        state[0] += a;
                    109:        state[1] += b;
                    110:        state[2] += c;
                    111:        state[3] += d;
                    112:        state[4] += e;
                    113:        /* Wipe variables */
                    114:        a = b = c = d = e = 0;
                    115:        memset(block, '\0', sizeof(block));
                    116: }
                    117: 
                    118: /**
                    119:  * Run your data through this. Also used in sha1_prf.
                    120:  */
                    121: void SHA1Update(private_sha1_hasher_t* this, uint8_t *data, uint32_t len)
                    122: {
                    123:        uint32_t i;
                    124:        uint32_t j;
                    125: 
                    126:        j = this->count[0];
                    127:        if ((this->count[0] += len << 3) < j)
                    128:        {
                    129:                this->count[1]++;
                    130:        }
                    131:        this->count[1] += (len>>29);
                    132:        j = (j >> 3) & 63;
                    133:        if ((j + len) > 63)
                    134:        {
                    135:                memcpy(&this->buffer[j], data, (i = 64-j));
                    136:                SHA1Transform(this->state, this->buffer);
                    137:                for ( ; i + 63 < len; i += 64)
                    138:                {
                    139:                    SHA1Transform(this->state, &data[i]);
                    140:                }
                    141:                j = 0;
                    142:        }
                    143:        else
                    144:        {
                    145:                i = 0;
                    146:        }
                    147:        memcpy(&this->buffer[j], &data[i], len - i);
                    148: }
                    149: 
                    150: 
                    151: /*
                    152:  * Add padding and return the message digest.
                    153:  */
                    154: static void SHA1Final(private_sha1_hasher_t *this, uint8_t *digest)
                    155: {
                    156:        uint32_t i;
                    157:        uint8_t finalcount[8];
                    158:        uint8_t c;
                    159: 
                    160:        for (i = 0; i < 8; i++)
                    161:        {
                    162:                finalcount[i] = (uint8_t)((this->count[(i >= 4 ? 0 : 1)]
                    163:                 >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
                    164:        }
                    165:        c = 0200;
                    166:        SHA1Update(this, &c, 1);
                    167:        while ((this->count[0] & 504) != 448)
                    168:        {
                    169:                c = 0000;
                    170:                SHA1Update(this, &c, 1);
                    171:        }
                    172:        SHA1Update(this, finalcount, 8);  /* Should cause a SHA1Transform() */
                    173:        for (i = 0; i < 20; i++)
                    174:        {
                    175:                digest[i] = (uint8_t)((this->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
                    176:        }
                    177: }
                    178: 
                    179: METHOD(hasher_t, reset, bool,
                    180:        private_sha1_hasher_t *this)
                    181: {
                    182:        this->state[0] = 0x67452301;
                    183:        this->state[1] = 0xEFCDAB89;
                    184:        this->state[2] = 0x98BADCFE;
                    185:        this->state[3] = 0x10325476;
                    186:        this->state[4] = 0xC3D2E1F0;
                    187:        this->count[0] = 0;
                    188:        this->count[1] = 0;
                    189: 
                    190:        return TRUE;
                    191: }
                    192: 
                    193: METHOD(hasher_t, get_hash, bool,
                    194:        private_sha1_hasher_t *this, chunk_t chunk, uint8_t *buffer)
                    195: {
                    196:        SHA1Update(this, chunk.ptr, chunk.len);
                    197:        if (buffer != NULL)
                    198:        {
                    199:                SHA1Final(this, buffer);
                    200:                reset(this);
                    201:        }
                    202:        return TRUE;
                    203: }
                    204: 
                    205: METHOD(hasher_t, allocate_hash, bool,
                    206:        private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash)
                    207: {
                    208:        SHA1Update(this, chunk.ptr, chunk.len);
                    209:        if (hash != NULL)
                    210:        {
                    211:                hash->ptr = malloc(HASH_SIZE_SHA1);
                    212:                hash->len = HASH_SIZE_SHA1;
                    213: 
                    214:                SHA1Final(this, hash->ptr);
                    215:                reset(this);
                    216:        }
                    217:        return TRUE;
                    218: }
                    219: 
                    220: METHOD(hasher_t, get_hash_size, size_t,
                    221:        private_sha1_hasher_t *this)
                    222: {
                    223:        return HASH_SIZE_SHA1;
                    224: }
                    225: 
                    226: METHOD(hasher_t, destroy, void,
                    227:        private_sha1_hasher_t *this)
                    228: {
                    229:        free(this);
                    230: }
                    231: 
                    232: /*
                    233:  * Described in header.
                    234:  */
                    235: sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo)
                    236: {
                    237:        private_sha1_hasher_t *this;
                    238: 
                    239:        if (algo != HASH_SHA1)
                    240:        {
                    241:                return NULL;
                    242:        }
                    243: 
                    244:        INIT(this,
                    245:                .public = {
                    246:                        .hasher_interface = {
                    247:                                .get_hash = _get_hash,
                    248:                                .allocate_hash = _allocate_hash,
                    249:                                .get_hash_size = _get_hash_size,
                    250:                                .reset = _reset,
                    251:                                .destroy = _destroy,
                    252:                        },
                    253:                },
                    254:        );
                    255: 
                    256:        /* initialize */
                    257:        reset(this);
                    258: 
                    259:        return &(this->public);
                    260: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>