gcrypt RSA private key implementation
[strongswan.git] / src / libstrongswan / plugins / gcrypt / gcrypt_hasher.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
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>.
9 *
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
13 * for more details.
14 */
15
16 #include "gcrypt_hasher.h"
17
18 #include <debug.h>
19
20 #include <gcrypt.h>
21
22 typedef struct private_gcrypt_hasher_t private_gcrypt_hasher_t;
23
24 /**
25 * Private data of gcrypt_hasher_t
26 */
27 struct private_gcrypt_hasher_t {
28
29 /**
30 * Public part of this class.
31 */
32 gcrypt_hasher_t public;
33
34 /**
35 * gcrypt hasher context
36 */
37 gcry_md_hd_t hd;
38 };
39
40 /**
41 * Implementation of hasher_t.get_hash_size.
42 */
43 static size_t get_hash_size(private_gcrypt_hasher_t *this)
44 {
45 return gcry_md_get_algo_dlen(gcry_md_get_algo(this->hd));
46 }
47
48 /**
49 * Implementation of hasher_t.reset.
50 */
51 static void reset(private_gcrypt_hasher_t *this)
52 {
53 gcry_md_reset(this->hd);
54 }
55
56 /**
57 * Implementation of hasher_t.get_hash.
58 */
59 static void get_hash(private_gcrypt_hasher_t *this, chunk_t chunk,
60 u_int8_t *hash)
61 {
62 gcry_md_write(this->hd, chunk.ptr, chunk.len);
63 if (hash)
64 {
65 memcpy(hash, gcry_md_read(this->hd, 0), get_hash_size(this));
66 gcry_md_reset(this->hd);
67 }
68 }
69
70 /**
71 * Implementation of hasher_t.allocate_hash.
72 */
73 static void allocate_hash(private_gcrypt_hasher_t *this, chunk_t chunk,
74 chunk_t *hash)
75 {
76 if (hash)
77 {
78 *hash = chunk_alloc(get_hash_size(this));
79 get_hash(this, chunk, hash->ptr);
80 }
81 else
82 {
83 get_hash(this, chunk, NULL);
84 }
85 }
86
87 /**
88 * Implementation of hasher_t.destroy.
89 */
90 static void destroy (private_gcrypt_hasher_t *this)
91 {
92 gcry_md_close(this->hd);
93 free(this);
94 }
95
96 /*
97 * Described in header
98 */
99 gcrypt_hasher_t *gcrypt_hasher_create(hash_algorithm_t algo)
100 {
101 private_gcrypt_hasher_t *this;
102 int gcrypt_alg;
103 gcry_error_t err;
104
105 switch (algo)
106 {
107 case HASH_MD2:
108 gcrypt_alg = GCRY_MD_MD2;
109 break;
110 case HASH_MD4:
111 gcrypt_alg = GCRY_MD_MD4;
112 break;
113 case HASH_MD5:
114 gcrypt_alg = GCRY_MD_MD5;
115 break;
116 case HASH_SHA1:
117 gcrypt_alg = GCRY_MD_SHA1;
118 break;
119 case HASH_SHA256:
120 gcrypt_alg = GCRY_MD_SHA256;
121 break;
122 case HASH_SHA384:
123 gcrypt_alg = GCRY_MD_SHA384;
124 break;
125 case HASH_SHA512:
126 gcrypt_alg = GCRY_MD_SHA512;
127 break;
128 default:
129 return NULL;
130 }
131
132 this = malloc_thing(private_gcrypt_hasher_t);
133
134 err = gcry_md_open(&this->hd, gcrypt_alg, 0);
135 if (err)
136 {
137 DBG1("grcy_md_open(%N) failed: %s",
138 hash_algorithm_names, algo, gpg_strerror(err));
139 free(this);
140 return NULL;
141 }
142
143 this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
144 this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
145 this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
146 this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
147 this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
148
149 return &this->public;
150 }
151