2 * Copyright (C) 2008 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "openssl_hasher.h"
20 #include <openssl/evp.h>
22 typedef struct private_openssl_hasher_t private_openssl_hasher_t
;
25 * Private data of openssl_hasher_t
27 struct private_openssl_hasher_t
{
30 * Public part of this class.
32 openssl_hasher_t
public;
35 * data collected to hash
46 * Mapping from the algorithms defined in IKEv2 to
47 * OpenSSL algorithm names
51 * Identifier specified in IKEv2
56 * Name of the algorithm, as used in OpenSSL
59 } openssl_algorithm_t
;
61 #define END_OF_LIST -1
64 * Algorithms for integrity
66 static openssl_algorithm_t integrity_algs
[] = {
70 {HASH_SHA256
, "sha256"},
71 {HASH_SHA384
, "sha384"},
72 {HASH_SHA512
, "sha512"},
77 * Look up an OpenSSL algorithm name
79 static char* lookup_algorithm(openssl_algorithm_t
*openssl_algo
,
82 while (openssl_algo
->ikev2_id
!= END_OF_LIST
)
84 if (ikev2_algo
== openssl_algo
->ikev2_id
)
86 return openssl_algo
->name
;
94 * append data to the to-be-hashed buffer
96 static void append_data(private_openssl_hasher_t
*this, chunk_t data
)
98 this->data
.ptr
= realloc(this->data
.ptr
, this->data
.len
+ data
.len
);
99 memcpy(this->data
.ptr
+ this->data
.len
, data
.ptr
, data
.len
);
100 this->data
.len
+= data
.len
;
104 * hash a buffer of data
106 static void hash_data(private_openssl_hasher_t
*this, chunk_t data
, u_int8_t
*digest
)
109 EVP_MD_CTX_init(&ctx
);
110 EVP_DigestInit_ex(&ctx
, this->hasher
, NULL
);
111 EVP_DigestUpdate(&ctx
, data
.ptr
, data
.len
);
112 EVP_DigestFinal_ex(&ctx
, digest
, NULL
);
113 EVP_MD_CTX_cleanup(&ctx
);
117 * Implementation of hasher_t.get_hash_size.
119 static size_t get_hash_size(private_openssl_hasher_t
*this)
121 return this->hasher
->md_size
;
125 * Implementation of hasher_t.reset.
127 static void reset(private_openssl_hasher_t
*this)
129 chunk_free(&this->data
);
133 * Implementation of hasher_t.get_hash.
135 static void get_hash(private_openssl_hasher_t
*this, chunk_t chunk
,
142 append_data(this, chunk
);
143 hash_data(this, this->data
, hash
);
146 { /* hash directly if no previous data found */
147 hash_data(this, chunk
, hash
);
153 append_data(this, chunk
);
158 * Implementation of hasher_t.allocate_hash.
160 static void allocate_hash(private_openssl_hasher_t
*this, chunk_t chunk
,
165 *hash
= chunk_alloc(get_hash_size(this));
166 get_hash(this, chunk
, hash
->ptr
);
170 get_hash(this, chunk
, NULL
);
175 * Implementation of hasher_t.destroy.
177 static void destroy (private_openssl_hasher_t
*this)
179 free(this->data
.ptr
);
184 * Described in header
186 openssl_hasher_t
*openssl_hasher_create(hash_algorithm_t algo
)
188 private_openssl_hasher_t
*this;
190 char* name
= lookup_algorithm(integrity_algs
, algo
);
193 /* algo unavailable */
197 this = malloc_thing(private_openssl_hasher_t
);
199 this->hasher
= EVP_get_digestbyname(name
);
202 /* OpenSSL does not support the requested algo */
207 this->public.hasher_interface
.get_hash
= (void (*) (hasher_t
*, chunk_t
, u_int8_t
*))get_hash
;
208 this->public.hasher_interface
.allocate_hash
= (void (*) (hasher_t
*, chunk_t
, chunk_t
*))allocate_hash
;
209 this->public.hasher_interface
.get_hash_size
= (size_t (*) (hasher_t
*))get_hash_size
;
210 this->public.hasher_interface
.reset
= (void (*) (hasher_t
*))reset
;
211 this->public.hasher_interface
.destroy
= (void (*) (hasher_t
*))destroy
;
213 this->data
= chunk_empty
;
215 return &this->public;