wolfssl: Add wolfSSL plugin for cryptographic implementations
[strongswan.git] / src / libstrongswan / plugins / wolfssl / wolfssl_sha1_prf.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
25 #ifndef NO_SHA
26
27 #include "wolfssl_sha1_prf.h"
28
29 #include <wolfssl/wolfcrypt/sha.h>
30 #include <crypto/hashers/hasher.h>
31
32 typedef struct private_wolfssl_sha1_prf_t private_wolfssl_sha1_prf_t;
33
34 /**
35 * Private data of an wolfssl_sha1_prf_t object.
36 */
37 struct private_wolfssl_sha1_prf_t {
38
39 /**
40 * Public wolfssl_sha1_prf_t interface.
41 */
42 wolfssl_sha1_prf_t public;
43
44 /**
45 * SHA1 context
46 */
47 wc_Sha sha1;
48 };
49
50 METHOD(prf_t, get_bytes, bool,
51 private_wolfssl_sha1_prf_t *this, chunk_t seed, uint8_t *bytes)
52 {
53 if (wc_ShaUpdate(&this->sha1, seed.ptr, seed.len) != 0)
54 {
55 return FALSE;
56 }
57
58 if (bytes)
59 {
60 uint32_t *hash = (uint32_t*)bytes;
61
62 hash[0] = htonl(this->sha1.digest[0]);
63 hash[1] = htonl(this->sha1.digest[1]);
64 hash[2] = htonl(this->sha1.digest[2]);
65 hash[3] = htonl(this->sha1.digest[3]);
66 hash[4] = htonl(this->sha1.digest[4]);
67 }
68
69 return TRUE;
70 }
71
72 METHOD(prf_t, get_block_size, size_t,
73 private_wolfssl_sha1_prf_t *this)
74 {
75 return HASH_SIZE_SHA1;
76 }
77
78 METHOD(prf_t, allocate_bytes, bool,
79 private_wolfssl_sha1_prf_t *this, chunk_t seed, chunk_t *chunk)
80 {
81 if (chunk)
82 {
83 *chunk = chunk_alloc(HASH_SIZE_SHA1);
84 return get_bytes(this, seed, chunk->ptr);
85 }
86 return get_bytes(this, seed, NULL);
87 }
88
89 METHOD(prf_t, get_key_size, size_t,
90 private_wolfssl_sha1_prf_t *this)
91 {
92 return HASH_SIZE_SHA1;
93 }
94
95 METHOD(prf_t, set_key, bool,
96 private_wolfssl_sha1_prf_t *this, chunk_t key)
97 {
98 if (wc_InitSha(&this->sha1) != 0)
99 {
100 return FALSE;
101 }
102
103 if (key.len % 4)
104 {
105 return FALSE;
106 }
107 if (key.len >= 4)
108 {
109 this->sha1.digest[0] ^= untoh32(key.ptr);
110 }
111 if (key.len >= 8)
112 {
113 this->sha1.digest[1] ^= untoh32(key.ptr + 4);
114 }
115 if (key.len >= 12)
116 {
117 this->sha1.digest[2] ^= untoh32(key.ptr + 8);
118 }
119 if (key.len >= 16)
120 {
121 this->sha1.digest[3] ^= untoh32(key.ptr + 12);
122 }
123 if (key.len >= 20)
124 {
125 this->sha1.digest[4] ^= untoh32(key.ptr + 16);
126 }
127 return TRUE;
128 }
129
130 METHOD(prf_t, destroy, void,
131 private_wolfssl_sha1_prf_t *this)
132 {
133 wc_ShaFree(&this->sha1);
134 free(this);
135 }
136
137 /**
138 * See header
139 */
140 wolfssl_sha1_prf_t *wolfssl_sha1_prf_create(pseudo_random_function_t algo)
141 {
142 private_wolfssl_sha1_prf_t *this;
143
144 if (algo != PRF_KEYED_SHA1)
145 {
146 return NULL;
147 }
148
149 INIT(this,
150 .public = {
151 .prf = {
152 .get_block_size = _get_block_size,
153 .get_bytes = _get_bytes,
154 .allocate_bytes = _allocate_bytes,
155 .get_key_size = _get_key_size,
156 .set_key = _set_key,
157 .destroy = _destroy,
158 },
159 },
160 );
161
162 if (wc_InitSha(&this->sha1) != 0)
163 {
164 free(this);
165 return NULL;
166 }
167
168 return &this->public;
169 }
170
171 #endif /* NO_SHA */