2 * Copyright (C) 2008 Thomas Kallenberg
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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>.
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
18 #include <arpa/inet.h>
21 #include "padlock_sha1_hasher.h"
23 #define PADLOCK_ALIGN __attribute__ ((__aligned__(16)))
25 typedef struct private_padlock_sha1_hasher_t private_padlock_sha1_hasher_t
;
28 * Private data structure with hasing context.
30 struct private_padlock_sha1_hasher_t
{
32 * Public interface for this hasher.
34 padlock_sha1_hasher_t
public;
37 * data collected to hash
43 * Invoke the actual padlock sha1() operation
45 static void padlock_sha1(int len
, u_char
*in
, u_char
*out
)
49 ".byte 0xf3, 0x0f, 0xa6, 0xc8"
55 * sha1() a buffer of data into digest
57 static void sha1(chunk_t data
, u_int32_t
*digest
)
59 u_int32_t hash
[128] PADLOCK_ALIGN
;
67 padlock_sha1(data
.len
, data
.ptr
, (u_char
*)hash
);
69 digest
[0] = bswap_32(hash
[0]);
70 digest
[1] = bswap_32(hash
[1]);
71 digest
[2] = bswap_32(hash
[2]);
72 digest
[3] = bswap_32(hash
[3]);
73 digest
[4] = bswap_32(hash
[4]);
77 * append data to the to-be-hashed buffer
79 static void append_data(private_padlock_sha1_hasher_t
*this, chunk_t data
)
81 this->data
.ptr
= realloc(this->data
.ptr
, this->data
.len
+ data
.len
);
82 memcpy(this->data
.ptr
+ this->data
.len
, data
.ptr
, data
.len
);
83 this->data
.len
+= data
.len
;
86 METHOD(hasher_t
, reset
, void,
87 private_padlock_sha1_hasher_t
*this)
89 chunk_free(&this->data
);
92 METHOD(hasher_t
, get_hash
, bool,
93 private_padlock_sha1_hasher_t
*this, chunk_t chunk
, u_int8_t
*hash
)
99 append_data(this, chunk
);
100 sha1(this->data
, (u_int32_t
*)hash
);
103 { /* hash directly if no previous data found */
104 sha1(chunk
, (u_int32_t
*)hash
);
110 append_data(this, chunk
);
115 METHOD(hasher_t
, allocate_hash
, bool,
116 private_padlock_sha1_hasher_t
*this, chunk_t chunk
, chunk_t
*hash
)
120 *hash
= chunk_alloc(HASH_SIZE_SHA1
);
121 return get_hash(this, chunk
, hash
->ptr
);
123 return get_hash(this, chunk
, NULL
);
126 METHOD(hasher_t
, get_hash_size
, size_t,
127 private_padlock_sha1_hasher_t
*this)
129 return HASH_SIZE_SHA1
;
132 METHOD(hasher_t
, destroy
, void,
133 private_padlock_sha1_hasher_t
*this)
135 free(this->data
.ptr
);
140 * Described in header.
142 padlock_sha1_hasher_t
*padlock_sha1_hasher_create(hash_algorithm_t algo
)
144 private_padlock_sha1_hasher_t
*this;
146 if (algo
!= HASH_SHA1
)
153 .get_hash
= _get_hash
,
154 .allocate_hash
= _allocate_hash
,
155 .get_hash_size
= _get_hash_size
,
161 return &this->public;