wolfssl: Add wolfSSL plugin for cryptographic implementations
[strongswan.git] / src / libstrongswan / plugins / wolfssl / wolfssl_util.c
1 /*
2 * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23 #include "wolfssl_common.h"
24 #include "wolfssl_util.h"
25
26 #include <utils/debug.h>
27
28 #include <wolfssl/wolfcrypt/hash.h>
29 #include <wolfssl/wolfcrypt/rsa.h>
30
31 /**
32 * Described in header.
33 */
34 bool wolfssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
35 {
36 int ret;
37
38 *hash = chunk_alloc(wc_HashGetDigestSize(hash_type));
39 ret = wc_Hash(hash_type, data.ptr, data.len, hash->ptr, hash->len);
40 if (ret < 0)
41 {
42 chunk_free(hash);
43 return FALSE;
44 }
45 return TRUE;
46 }
47
48 /**
49 * Described in header.
50 */
51 bool wolfssl_mp2chunk(mp_int *mp, chunk_t *chunk)
52 {
53 *chunk = chunk_alloc(mp_unsigned_bin_size(mp));
54 if (mp_to_unsigned_bin(mp, chunk->ptr) == 0)
55 {
56 if (chunk->len && chunk->ptr[0] & 0x80)
57 { /* if MSB is set, prepend a zero to make it non-negative */
58 *chunk = chunk_cat("cm", chunk_from_chars(0x00), *chunk);
59 }
60 return TRUE;
61 }
62 chunk_free(chunk);
63 return FALSE;
64 }
65
66 /**
67 * Described in header.
68 */
69 bool wolfssl_mp_split(chunk_t chunk, mp_int *a, mp_int *b)
70 {
71 int ret;
72 int len;
73
74 if ((chunk.len % 2) == 1)
75 {
76 return FALSE;
77 }
78
79 len = chunk.len / 2;
80 ret = mp_read_unsigned_bin(a, chunk.ptr, len);
81 if (ret == 0)
82 {
83 ret = mp_read_unsigned_bin(b, chunk.ptr + len, len);
84 }
85
86 return ret == 0;
87 }
88
89 /**
90 * Described in header.
91 */
92 bool wolfssl_mp_cat(int len, mp_int *a, mp_int *b, chunk_t *chunk)
93 {
94 int ret;
95 int sz;
96
97 *chunk = chunk_alloc(len);
98 if (b != NULL)
99 {
100 len /= 2;
101 }
102
103 sz = mp_unsigned_bin_size(a);
104 memset(chunk->ptr, 0, len - sz);
105 ret = mp_to_unsigned_bin(a, chunk->ptr + len - sz);
106 if (ret == 0 && b != NULL)
107 {
108 sz = mp_unsigned_bin_size(b);
109 memset(chunk->ptr + len, 0, len - sz);
110 ret = mp_to_unsigned_bin(b, chunk->ptr + 2 * len - sz);
111 }
112
113 return ret == 0;
114 }
115
116 /**
117 * Described in header.
118 */
119 bool wolfssl_hash2type(hash_algorithm_t hash, enum wc_HashType *type)
120 {
121 switch (hash)
122 {
123 #ifndef NO_MD5
124 case HASH_MD5:
125 *type = WC_HASH_TYPE_MD5;
126 break;
127 #endif
128 #ifndef NO_SHA
129 case HASH_SHA1:
130 *type = WC_HASH_TYPE_SHA;
131 break;
132 #endif
133 #ifdef WOLFSSL_SHA224
134 case HASH_SHA224:
135 *type = WC_HASH_TYPE_SHA224;
136 break;
137 #endif
138 #ifndef NO_SHA256
139 case HASH_SHA256:
140 *type = WC_HASH_TYPE_SHA256;
141 break;
142 #endif
143 #ifdef WOLFSSL_SHA384
144 case HASH_SHA384:
145 *type = WC_HASH_TYPE_SHA384;
146 break;
147 #endif
148 #ifdef WOLFSSL_SHA512
149 case HASH_SHA512:
150 *type = WC_HASH_TYPE_SHA512;
151 break;
152 #endif
153 default:
154 return FALSE;
155 }
156 return TRUE;
157 }
158
159 /**
160 * Described in header.
161 */
162 bool wolfssl_hash2mgf1(hash_algorithm_t hash, int *mgf1)
163 {
164 switch (hash)
165 {
166 #ifndef NO_SHA
167 case HASH_SHA1:
168 *mgf1 = WC_MGF1SHA1;
169 break;
170 #endif
171 #ifdef WOLFSSL_SHA224
172 case HASH_SHA224:
173 *mgf1 = WC_MGF1SHA224;
174 break;
175 #endif
176 #ifndef NO_SHA256
177 case HASH_SHA256:
178 *mgf1 = WC_MGF1SHA256;
179 break;
180 #endif
181 #ifdef WOLFSSL_SHA384
182 case HASH_SHA384:
183 *mgf1 = WC_MGF1SHA384;
184 break;
185 #endif
186 #ifdef WOLFSSL_SHA512
187 case HASH_SHA512:
188 *mgf1 = WC_MGF1SHA512;
189 break;
190 #endif
191 default:
192 return FALSE;
193 }
194 return TRUE;
195 }