summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/gost/gost89imit_pmeth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/gost/gost89imit_pmeth.c')
-rw-r--r--src/lib/libcrypto/gost/gost89imit_pmeth.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/lib/libcrypto/gost/gost89imit_pmeth.c b/src/lib/libcrypto/gost/gost89imit_pmeth.c
new file mode 100644
index 0000000000..ec9c72372c
--- /dev/null
+++ b/src/lib/libcrypto/gost/gost89imit_pmeth.c
@@ -0,0 +1,230 @@
1/* $OpenBSD: gost89imit_pmeth.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */
2/*
3 * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
4 * Copyright (c) 2005-2006 Cryptocom LTD
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. All advertising materials mentioning features or use of this
19 * software must display the following acknowledgment:
20 * "This product includes software developed by the OpenSSL Project
21 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22 *
23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24 * endorse or promote products derived from this software without
25 * prior written permission. For written permission, please contact
26 * openssl-core@openssl.org.
27 *
28 * 5. Products derived from this software may not be called "OpenSSL"
29 * nor may "OpenSSL" appear in their names without prior written
30 * permission of the OpenSSL Project.
31 *
32 * 6. Redistributions of any form whatsoever must retain the following
33 * acknowledgment:
34 * "This product includes software developed by the OpenSSL Project
35 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48 * OF THE POSSIBILITY OF SUCH DAMAGE.
49 * ====================================================================
50 */
51
52#include <string.h>
53
54#include <openssl/opensslconf.h>
55
56#ifndef OPENSSL_NO_GOST
57#include <openssl/evp.h>
58#include <openssl/err.h>
59#include <openssl/gost.h>
60#include <openssl/x509v3.h> /*For string_to_hex */
61
62#include "evp_locl.h"
63#include "gost_locl.h"
64
65struct gost_mac_pmeth_data {
66 EVP_MD *md;
67 unsigned char key[32];
68 unsigned key_set : 1;
69};
70
71static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
72{
73 struct gost_mac_pmeth_data *data;
74
75 data = calloc(1, sizeof(struct gost_mac_pmeth_data));
76 if (!data)
77 return 0;
78 EVP_PKEY_CTX_set_data(ctx,data);
79 return 1;
80}
81
82static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
83{
84 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
85 free(data);
86}
87
88static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
89{
90 struct gost_mac_pmeth_data *dst_data, *src_data;
91
92 if (!pkey_gost_mac_init(dst))
93 return 0;
94
95 src_data = EVP_PKEY_CTX_get_data(src);
96 dst_data = EVP_PKEY_CTX_get_data(dst);
97
98 *dst_data = *src_data;
99
100 return 1;
101}
102
103static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
104{
105 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
106 unsigned char *keydata;
107
108 if (!data->key_set) {
109 GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET);
110 return 0;
111 }
112
113 keydata = malloc(32);
114 memcpy(keydata, data->key, 32);
115 EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
116
117 return 1;
118}
119
120static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
121{
122 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
123
124 switch (type) {
125 case EVP_PKEY_CTRL_MD:
126 if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) {
127 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
128 return 0;
129 }
130 data->md = p2;
131 return 1;
132
133 case EVP_PKEY_CTRL_SET_MAC_KEY:
134 if (p1 != 32) {
135 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
136 return 0;
137 }
138
139 memcpy(data->key, p2, 32);
140 data->key_set = 1;
141 return 1;
142
143 case EVP_PKEY_CTRL_DIGESTINIT:
144 {
145 EVP_MD_CTX *mctx = p2;
146 void *key;
147 if (!data->key_set) {
148 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
149 if (!pkey) {
150 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_MAC_KEY_NOT_SET);
151 return 0;
152 }
153 key = EVP_PKEY_get0(pkey);
154 if (!key) {
155 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_MAC_KEY_NOT_SET);
156 return 0;
157 }
158 } else {
159 key = &(data->key);
160 }
161 if (!mctx->digest->md_ctrl)
162 return 0;
163 return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32 * 8, key);
164 }
165
166 }
167
168 return -2;
169}
170static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
171 const char *type, const char *value)
172{
173 if (!value)
174 return 0;
175 if (!strcmp(type, "key")) {
176 void *p = (void *)value;
177 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, strlen(value), p);
178 }
179 if (!strcmp(type, "hexkey")) {
180 unsigned char *key;
181 int r;
182 long keylen;
183 key = string_to_hex(value, &keylen);
184 if (!key)
185 return 0;
186 r = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
187 free(key);
188 return r;
189 }
190 return -2;
191}
192
193static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
194{
195 return 1;
196}
197
198static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
199{
200 unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
201 int ret;
202
203
204 if (!sig) {
205 *siglen = 4;
206 return 1;
207 }
208
209 ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
210 *siglen = tmpsiglen;
211 return ret;
212}
213
214const EVP_PKEY_METHOD gostimit_pkey_meth = {
215 .pkey_id = EVP_PKEY_GOSTIMIT,
216
217 .init = pkey_gost_mac_init,
218 .cleanup = pkey_gost_mac_cleanup,
219 .copy = pkey_gost_mac_copy,
220
221 .keygen = pkey_gost_mac_keygen,
222
223 .signctx_init = pkey_gost_mac_signctx_init,
224 .signctx = pkey_gost_mac_signctx,
225
226 .ctrl = pkey_gost_mac_ctrl,
227 .ctrl_str = pkey_gost_mac_ctrl_str,
228};
229
230#endif