Return to padlock_sha1_hasher.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / padlock |
1.1 misho 1: /* 2: * Copyright (C) 2008 Thomas Kallenberg 3: * Copyright (C) 2008 Martin Willi 4: * HSR Hochschule fuer Technik Rapperswil 5: * 6: * This program is free software; you can redistribute it and/or modify it 7: * under the terms of the GNU General Public License as published by the 8: * Free Software Foundation; either version 2 of the License, or (at your 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 10: * 11: * This program is distributed in the hope that it will be useful, but 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14: * for more details. 15: */ 16: 17: #include <string.h> 18: #include <arpa/inet.h> 19: 20: #include "padlock_sha1_hasher.h" 21: 22: #define PADLOCK_ALIGN __attribute__ ((__aligned__(16))) 23: 24: typedef struct private_padlock_sha1_hasher_t private_padlock_sha1_hasher_t; 25: 26: /** 27: * Private data structure with hashing context. 28: */ 29: struct private_padlock_sha1_hasher_t { 30: /** 31: * Public interface for this hasher. 32: */ 33: padlock_sha1_hasher_t public; 34: 35: /** 36: * data collected to hash 37: */ 38: chunk_t data; 39: }; 40: 41: /** 42: * Invoke the actual padlock sha1() operation 43: */ 44: static void padlock_sha1(int len, u_char *in, u_char *out) 45: { 46: /* rep xsha1 */ 47: asm volatile ( 48: ".byte 0xf3, 0x0f, 0xa6, 0xc8" 49: : "+S"(in), "+D"(out) 50: : "c"(len), "a"(0)); 51: } 52: 53: /** 54: * sha1() a buffer of data into digest 55: */ 56: static void sha1(chunk_t data, uint32_t *digest) 57: { 58: uint32_t hash[128] PADLOCK_ALIGN; 59: 60: hash[0] = 0x67452301; 61: hash[1] = 0xefcdab89; 62: hash[2] = 0x98badcfe; 63: hash[3] = 0x10325476; 64: hash[4] = 0xc3d2e1f0; 65: 66: padlock_sha1(data.len, data.ptr, (u_char*)hash); 67: 68: digest[0] = __builtin_bswap32(hash[0]); 69: digest[1] = __builtin_bswap32(hash[1]); 70: digest[2] = __builtin_bswap32(hash[2]); 71: digest[3] = __builtin_bswap32(hash[3]); 72: digest[4] = __builtin_bswap32(hash[4]); 73: } 74: 75: /** 76: * append data to the to-be-hashed buffer 77: */ 78: static void append_data(private_padlock_sha1_hasher_t *this, chunk_t data) 79: { 80: this->data.ptr = realloc(this->data.ptr, this->data.len + data.len); 81: memcpy(this->data.ptr + this->data.len, data.ptr, data.len); 82: this->data.len += data.len; 83: } 84: 85: METHOD(hasher_t, reset, bool, 86: private_padlock_sha1_hasher_t *this) 87: { 88: chunk_free(&this->data); 89: return TRUE; 90: } 91: 92: METHOD(hasher_t, get_hash, bool, 93: private_padlock_sha1_hasher_t *this, chunk_t chunk, uint8_t *hash) 94: { 95: if (hash) 96: { 97: if (this->data.len) 98: { 99: append_data(this, chunk); 100: sha1(this->data, (uint32_t*)hash); 101: } 102: else 103: { /* hash directly if no previous data found */ 104: sha1(chunk, (uint32_t*)hash); 105: } 106: reset(this); 107: } 108: else 109: { 110: append_data(this, chunk); 111: } 112: return TRUE; 113: } 114: 115: METHOD(hasher_t, allocate_hash, bool, 116: private_padlock_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash) 117: { 118: if (hash) 119: { 120: *hash = chunk_alloc(HASH_SIZE_SHA1); 121: return get_hash(this, chunk, hash->ptr); 122: } 123: return get_hash(this, chunk, NULL); 124: } 125: 126: METHOD(hasher_t, get_hash_size, size_t, 127: private_padlock_sha1_hasher_t *this) 128: { 129: return HASH_SIZE_SHA1; 130: } 131: 132: METHOD(hasher_t, destroy, void, 133: private_padlock_sha1_hasher_t *this) 134: { 135: free(this->data.ptr); 136: free(this); 137: } 138: 139: /* 140: * Described in header. 141: */ 142: padlock_sha1_hasher_t *padlock_sha1_hasher_create(hash_algorithm_t algo) 143: { 144: private_padlock_sha1_hasher_t *this; 145: 146: if (algo != HASH_SHA1) 147: { 148: return NULL; 149: } 150: INIT(this, 151: .public = { 152: .hasher = { 153: .get_hash = _get_hash, 154: .allocate_hash = _allocate_hash, 155: .get_hash_size = _get_hash_size, 156: .reset = _reset, 157: .destroy = _destroy, 158: }, 159: }, 160: ); 161: return &this->public; 162: }