76e1ce50ecd7c7c6f86c3a45c3f7e037456c510f
[strongswan.git] / src / libstrongswan / crypto / signers / hmac_signer.c
1 /**
2 * @file hmac_signer.c
3 *
4 * @brief Implementation of hmac_signer_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <string.h>
25
26 #include "hmac_signer.h"
27
28 #include <crypto/prfs/hmac_prf.h>
29
30 typedef struct private_hmac_signer_t private_hmac_signer_t;
31
32 /**
33 * Private data structure with signing context.
34 */
35 struct private_hmac_signer_t {
36 /**
37 * Public interface of hmac_signer_t.
38 */
39 hmac_signer_t public;
40
41 /**
42 * Assigned hmac function.
43 */
44 prf_t *hmac_prf;
45
46 /**
47 * Block size (truncation of HMAC Hash)
48 */
49 size_t block_size;
50 };
51
52 /**
53 * Implementation of signer_t.get_signature.
54 */
55 static void get_signature (private_hmac_signer_t *this, chunk_t data, u_int8_t *buffer)
56 {
57 u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
58
59 this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
60
61 /* copy MAC depending on truncation */
62 memcpy(buffer, full_mac, this->block_size);
63 }
64
65 /**
66 * Implementation of signer_t.allocate_signature.
67 */
68 static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk_t *chunk)
69 {
70 chunk_t signature;
71 u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
72
73 this->hmac_prf->get_bytes(this->hmac_prf,data,full_mac);
74
75 signature.ptr = malloc(this->block_size);
76 signature.len = this->block_size;
77
78 /* copy signature */
79 memcpy(signature.ptr, full_mac, this->block_size);
80
81 *chunk = signature;
82 }
83
84 /**
85 * Implementation of signer_t.verify_signature.
86 */
87 static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t signature)
88 {
89 u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
90
91 this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
92
93 if (signature.len != this->block_size)
94 {
95 return FALSE;
96 }
97
98 /* compare mac aka signature :-) */
99 if (memcmp(signature.ptr, full_mac, this->block_size) == 0)
100 {
101 return TRUE;
102 }
103 else
104 {
105 return FALSE;
106 }
107 }
108
109 /**
110 * Implementation of signer_t.get_key_size.
111 */
112 static size_t get_key_size(private_hmac_signer_t *this)
113 {
114 /* for HMAC signer, IKEv2 uses block size as key size */
115 return this->hmac_prf->get_block_size(this->hmac_prf);
116 }
117
118 /**
119 * Implementation of signer_t.get_block_size.
120 */
121 static size_t get_block_size(private_hmac_signer_t *this)
122 {
123 return this->block_size;
124 }
125
126 /**
127 * Implementation of signer_t.set_key.
128 */
129 static void set_key(private_hmac_signer_t *this, chunk_t key)
130 {
131 this->hmac_prf->set_key(this->hmac_prf, key);
132 }
133
134 /**
135 * Implementation of signer_t.destroy.
136 */
137 static status_t destroy(private_hmac_signer_t *this)
138 {
139 this->hmac_prf->destroy(this->hmac_prf);
140 free(this);
141 return SUCCESS;
142 }
143
144 /*
145 * Described in header
146 */
147 hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_size)
148 {
149 size_t hmac_block_size;
150 private_hmac_signer_t *this = malloc_thing(private_hmac_signer_t);
151
152 this->hmac_prf = (prf_t *) hmac_prf_create(hash_algoritm);
153 if (this->hmac_prf == NULL)
154 {
155 /* algorithm not supported */
156 free(this);
157 return NULL;
158 }
159
160 /* prevent invalid truncation */
161 hmac_block_size = this->hmac_prf->get_block_size(this->hmac_prf);
162 this->block_size = min(block_size, hmac_block_size);
163
164 /* interface functions */
165 this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
166 this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
167 this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature;
168 this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size;
169 this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size;
170 this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key;
171 this->public.signer_interface.destroy = (void (*) (signer_t*))destroy;
172
173 return &(this->public);
174 }