implemented XCBC algorithms (signer, prf) for IKE on top of a crypter
[strongswan.git] / src / libstrongswan / plugins / xcbc / xcbc_signer.c
1 /*
2 * Copyright (C) 2008 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 * $Id$
16 */
17
18 #include <string.h>
19
20 #include "xcbc_signer.h"
21 #include "xcbc.h"
22
23 typedef struct private_xcbc_signer_t private_xcbc_signer_t;
24
25 /**
26 * Private data structure with signing context.
27 */
28 struct private_xcbc_signer_t {
29
30 /**
31 * Public interface of xcbc_signer_t.
32 */
33 xcbc_signer_t public;
34
35 /**
36 * Assigned xcbc function.
37 */
38 xcbc_t *xcbc;
39
40 /**
41 * Block size (truncation of XCBC MAC)
42 */
43 size_t block_size;
44 };
45
46 /**
47 * Implementation of signer_t.get_signature.
48 */
49 static void get_signature(private_xcbc_signer_t *this,
50 chunk_t data, u_int8_t *buffer)
51 {
52 if (buffer == NULL)
53 { /* append mode */
54 this->xcbc->get_mac(this->xcbc, data, NULL);
55 }
56 else
57 {
58 u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
59
60 this->xcbc->get_mac(this->xcbc, data, mac);
61 memcpy(buffer, mac, this->block_size);
62 }
63 }
64
65 /**
66 * Implementation of signer_t.allocate_signature.
67 */
68 static void allocate_signature (private_xcbc_signer_t *this,
69 chunk_t data, chunk_t *chunk)
70 {
71 if (chunk == NULL)
72 { /* append mode */
73 this->xcbc->get_mac(this->xcbc, data, NULL);
74 }
75 else
76 {
77 u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
78
79 this->xcbc->get_mac(this->xcbc, data, mac);
80
81 chunk->ptr = malloc(this->block_size);
82 chunk->len = this->block_size;
83
84 memcpy(chunk->ptr, mac, this->block_size);
85 }
86 }
87
88 /**
89 * Implementation of signer_t.verify_signature.
90 */
91 static bool verify_signature(private_xcbc_signer_t *this,
92 chunk_t data, chunk_t signature)
93 {
94 u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
95
96 if (signature.len != this->block_size)
97 {
98 return FALSE;
99 }
100
101 this->xcbc->get_mac(this->xcbc, data, mac);
102 return memeq(signature.ptr, mac, this->block_size);
103 }
104
105 /**
106 * Implementation of signer_t.get_key_size.
107 */
108 static size_t get_key_size(private_xcbc_signer_t *this)
109 {
110 return this->xcbc->get_block_size(this->xcbc);
111 }
112
113 /**
114 * Implementation of signer_t.get_block_size.
115 */
116 static size_t get_block_size(private_xcbc_signer_t *this)
117 {
118 return this->block_size;
119 }
120
121 /**
122 * Implementation of signer_t.set_key.
123 */
124 static void set_key(private_xcbc_signer_t *this, chunk_t key)
125 {
126 this->xcbc->set_key(this->xcbc, key);
127 }
128
129 /**
130 * Implementation of signer_t.destroy.
131 */
132 static status_t destroy(private_xcbc_signer_t *this)
133 {
134 this->xcbc->destroy(this->xcbc);
135 free(this);
136 return SUCCESS;
137 }
138
139 /*
140 * Described in header
141 */
142 xcbc_signer_t *xcbc_signer_create(integrity_algorithm_t algo)
143 {
144 private_xcbc_signer_t *this;
145 size_t trunc;
146 xcbc_t *xcbc;
147
148 switch (algo)
149 {
150 case AUTH_AES_XCBC_96:
151 xcbc = xcbc_create(ENCR_AES_CBC, 16);
152 trunc = 12;
153 break;
154 default:
155 return NULL;
156 }
157 if (xcbc == NULL)
158 {
159 return NULL;
160 }
161
162 this = malloc_thing(private_xcbc_signer_t);
163 this->xcbc = xcbc;
164 this->block_size = min(trunc, xcbc->get_block_size(xcbc));
165
166 /* interface functions */
167 this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
168 this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
169 this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature;
170 this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size;
171 this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size;
172 this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key;
173 this->public.signer_interface.destroy = (void (*) (signer_t*))destroy;
174
175 return &this->public;
176 }
177