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