]>
Commit | Line | Data |
---|---|---|
a04549cc | 1 | /********************************************************************** |
926c41bd | 2 | * gost_eng.c * |
a04549cc DSH |
3 | * Copyright (c) 2005-2006 Cryptocom LTD * |
4 | * This file is distributed under the same license as OpenSSL * | |
5 | * * | |
6 | * Main file of GOST engine * | |
7 | * for OpenSSL * | |
8 | * Requires OpenSSL 0.9.9 for compilation * | |
9 | **********************************************************************/ | |
10 | #include <string.h> | |
11 | #include <openssl/evp.h> | |
12 | #include <openssl/engine.h> | |
13 | #include <openssl/obj_mac.h> | |
14 | #include "e_gost_err.h" | |
926c41bd | 15 | #include "gost_lcl.h" |
a04549cc DSH |
16 | static const char *engine_gost_id = "gost"; |
17 | static const char *engine_gost_name = "Reference implementation of GOST engine"; | |
18 | ||
19 | /* Symmetric cipher and digest function registrar */ | |
20 | ||
21 | static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |
926c41bd | 22 | const int **nids, int nid); |
a04549cc DSH |
23 | |
24 | static int gost_digests(ENGINE *e, const EVP_MD **digest, | |
926c41bd | 25 | const int **nids, int ind); |
a04549cc DSH |
26 | |
27 | static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, | |
926c41bd | 28 | const int **nids, int nid); |
a04549cc DSH |
29 | |
30 | static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, | |
926c41bd | 31 | const int **nids, int nid); |
a04549cc DSH |
32 | |
33 | static int gost_cipher_nids[] = | |
9981a51e | 34 | {NID_id_Gost28147_89, NID_gost89_cnt,0}; |
a04549cc DSH |
35 | |
36 | static int gost_digest_nids[] = | |
37 | {NID_id_GostR3411_94, 0}; | |
38 | ||
39 | static int gost_pkey_meth_nids[] = | |
40 | {NID_id_GostR3410_94_cc, NID_id_GostR3410_94, NID_id_GostR3410_2001_cc, | |
926c41bd | 41 | NID_id_GostR3410_2001, 0}; |
a04549cc DSH |
42 | |
43 | static EVP_PKEY_METHOD *pmeth_GostR3410_94_cc = NULL, *pmeth_GostR3410_94 = NULL, | |
44 | *pmeth_GostR3410_2001_cc = NULL, *pmeth_GostR3410_2001 = NULL; | |
45 | ||
46 | static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94_cc = NULL, *ameth_GostR3410_94 = NULL, | |
47 | *ameth_GostR3410_2001_cc = NULL, *ameth_GostR3410_2001 = NULL; | |
48 | ||
49 | ||
926c41bd DSH |
50 | static int gost_engine_init(ENGINE *e) |
51 | { | |
a04549cc | 52 | return 1; |
926c41bd DSH |
53 | } |
54 | ||
55 | static int gost_engine_finish(ENGINE *e) | |
56 | { | |
a04549cc | 57 | return 1; |
926c41bd | 58 | } |
a04549cc | 59 | |
926c41bd DSH |
60 | static int gost_engine_destroy(ENGINE *e) |
61 | { | |
a04549cc | 62 | return 1; |
926c41bd | 63 | } |
a04549cc | 64 | |
926c41bd DSH |
65 | static int bind_gost (ENGINE *e,const char *id) |
66 | { | |
a04549cc DSH |
67 | int ret = 0; |
68 | if (id && strcmp(id, engine_gost_id)) return 0; | |
69 | ||
926c41bd DSH |
70 | if (!ENGINE_set_id(e, engine_gost_id)) |
71 | { | |
a04549cc DSH |
72 | printf("ENGINE_set_id failed\n"); |
73 | goto end; | |
926c41bd DSH |
74 | } |
75 | if (!ENGINE_set_name(e, engine_gost_name)) | |
76 | { | |
a04549cc DSH |
77 | printf("ENGINE_set_name failed\n"); |
78 | goto end; | |
926c41bd DSH |
79 | } |
80 | if (!ENGINE_set_digests(e, gost_digests)) | |
81 | { | |
a04549cc DSH |
82 | printf("ENGINE_set_digests failed\n"); |
83 | goto end; | |
926c41bd DSH |
84 | } |
85 | if (! ENGINE_set_ciphers(e, gost_ciphers)) | |
86 | { | |
a04549cc DSH |
87 | printf("ENGINE_set_ciphers failed\n"); |
88 | goto end; | |
926c41bd DSH |
89 | } |
90 | if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) | |
91 | { | |
a04549cc DSH |
92 | printf("ENGINE_set_pkey_meths failed\n"); |
93 | goto end; | |
926c41bd DSH |
94 | } |
95 | if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) | |
96 | { | |
a04549cc DSH |
97 | printf("ENGINE_set_pkey_asn1_meths failed\n"); |
98 | goto end; | |
926c41bd DSH |
99 | } |
100 | /* Control function and commands */ | |
101 | if (!ENGINE_set_cmd_defns(e,gost_cmds)) | |
102 | { | |
103 | fprintf(stderr,"ENGINE_set_cmd_defns failed\n"); | |
104 | goto end; | |
105 | } | |
106 | if (!ENGINE_set_ctrl_function(e,gost_control_func)) | |
107 | { | |
108 | fprintf(stderr,"ENGINE_set_ctrl_func failed\n"); | |
109 | goto end; | |
110 | } | |
a04549cc DSH |
111 | if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy) |
112 | || ! ENGINE_set_init_function(e,gost_engine_init) | |
926c41bd DSH |
113 | || ! ENGINE_set_finish_function(e,gost_engine_finish)) |
114 | { | |
115 | goto end; | |
116 | } | |
a04549cc DSH |
117 | |
118 | if (!register_ameth_gost(NID_id_GostR3410_94_cc, &ameth_GostR3410_94_cc, "GOST94CC", "GOST R 34.10-94, Cryptocom LTD implementation")) goto end; | |
119 | if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end; | |
120 | if (!register_ameth_gost(NID_id_GostR3410_2001_cc, &ameth_GostR3410_2001_cc, "GOST2001CC", "GOST R 34.10-2001, Cryptocom LTD implementation")) goto end; | |
121 | if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end; | |
122 | ||
123 | if (!register_pmeth_gost(NID_id_GostR3410_94_cc, &pmeth_GostR3410_94_cc, 0)) goto end; | |
124 | if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end; | |
125 | if (!register_pmeth_gost(NID_id_GostR3410_2001_cc, &pmeth_GostR3410_2001_cc, 0)) goto end; | |
126 | if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end; | |
127 | if ( ! ENGINE_register_ciphers(e) | |
128 | || ! ENGINE_register_digests(e) | |
129 | || ! ENGINE_register_pkey_meths(e) | |
130 | /* These two actually should go in LIST_ADD command */ | |
131 | || ! EVP_add_cipher(&cipher_gost) | |
9981a51e | 132 | || ! EVP_add_cipher(&cipher_gost_cpacnt) |
a04549cc | 133 | || ! EVP_add_digest(&digest_gost) |
926c41bd DSH |
134 | ) |
135 | { | |
136 | goto end; | |
137 | } | |
a04549cc DSH |
138 | |
139 | ERR_load_GOST_strings(); | |
140 | ret = 1; | |
926c41bd | 141 | end: |
a04549cc | 142 | return ret; |
926c41bd | 143 | } |
a04549cc | 144 | |
afda1385 | 145 | #ifndef OPENSSL_NO_DYNAMIC_ENGINE |
44181ea8 | 146 | IMPLEMENT_DYNAMIC_BIND_FN(bind_gost) |
44181ea8 | 147 | IMPLEMENT_DYNAMIC_CHECK_FN() |
afda1385 | 148 | #endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */ |
a04549cc DSH |
149 | |
150 | static int gost_digests(ENGINE *e, const EVP_MD **digest, | |
926c41bd DSH |
151 | const int **nids, int nid) |
152 | { | |
a04549cc | 153 | int ok =1 ; |
926c41bd DSH |
154 | if (!digest) |
155 | { | |
a04549cc DSH |
156 | *nids = gost_digest_nids; |
157 | return 1; | |
926c41bd | 158 | } |
44181ea8 | 159 | /*printf("Digest no %d requested\n",nid);*/ |
926c41bd DSH |
160 | if(nid == NID_id_GostR3411_94) |
161 | { | |
162 | *digest = &digest_gost; | |
163 | } | |
164 | else | |
165 | { | |
166 | ok =0; | |
167 | *digest = NULL; | |
a04549cc DSH |
168 | } |
169 | return ok; | |
926c41bd | 170 | } |
a04549cc DSH |
171 | |
172 | static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher, | |
926c41bd DSH |
173 | const int **nids, int nid) |
174 | { | |
a04549cc | 175 | int ok = 1; |
926c41bd DSH |
176 | if (!cipher) |
177 | { | |
a04549cc | 178 | *nids = gost_cipher_nids; |
9981a51e | 179 | return 2; /* two ciphers are supported */ |
926c41bd | 180 | } |
a04549cc | 181 | |
926c41bd DSH |
182 | if(nid == NID_id_Gost28147_89) |
183 | { | |
184 | *cipher = &cipher_gost; | |
185 | } | |
9981a51e DSH |
186 | else if (nid == NID_gost89_cnt) |
187 | { | |
188 | *cipher = &cipher_gost_cpacnt; | |
189 | } | |
190 | else | |
926c41bd | 191 | { |
a04549cc DSH |
192 | ok = 0; |
193 | *cipher = NULL; | |
926c41bd | 194 | } |
a04549cc | 195 | return ok; |
926c41bd | 196 | } |
a04549cc DSH |
197 | |
198 | static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, | |
926c41bd DSH |
199 | const int **nids, int nid) |
200 | { | |
201 | if (!pmeth) | |
202 | { | |
a04549cc DSH |
203 | *nids = gost_pkey_meth_nids; |
204 | return 4; | |
926c41bd | 205 | } |
a04549cc | 206 | |
926c41bd DSH |
207 | switch (nid) |
208 | { | |
209 | case NID_id_GostR3410_94_cc: *pmeth = pmeth_GostR3410_94_cc; return 1; | |
210 | case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1; | |
211 | case NID_id_GostR3410_2001_cc: *pmeth = pmeth_GostR3410_2001_cc; return 1; | |
212 | case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; | |
213 | default:; | |
214 | } | |
a04549cc DSH |
215 | |
216 | *pmeth = NULL; | |
217 | return 0; | |
926c41bd | 218 | } |
a04549cc DSH |
219 | |
220 | static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, | |
926c41bd DSH |
221 | const int **nids, int nid) |
222 | { | |
223 | if (!ameth) | |
224 | { | |
a04549cc DSH |
225 | *nids = gost_pkey_meth_nids; |
226 | return 4; | |
926c41bd DSH |
227 | } |
228 | switch (nid) | |
229 | { | |
230 | case NID_id_GostR3410_94_cc: *ameth = ameth_GostR3410_94_cc; return 1; | |
231 | case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1; | |
232 | case NID_id_GostR3410_2001_cc: *ameth = ameth_GostR3410_2001_cc; return 1; | |
233 | case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; | |
234 | default:; | |
235 | } | |
a04549cc DSH |
236 | |
237 | *ameth = NULL; | |
238 | return 0; | |
926c41bd DSH |
239 | } |
240 | ||
241 | #ifdef OPENSSL_NO_DYNAMIC_ENGINE | |
242 | static ENGINE *engine_gost(void) | |
243 | { | |
244 | ENGINE *ret = ENGINE_new(); | |
245 | if (!ret) | |
246 | return NULL; | |
247 | if (!bind_gost(ret,engine_gost_id)) | |
248 | { | |
249 | ENGINE_free(ret); | |
250 | return NULL; | |
251 | } | |
252 | return ret; | |
253 | } | |
254 | ||
255 | void ENGINE_load_gost(void) | |
256 | { | |
257 | ENGINE *toadd =engine_gost(); | |
258 | if (!toadd) return; | |
259 | ENGINE_add(toadd); | |
260 | ENGINE_free(toadd); | |
261 | ERR_clear_error(); | |
262 | } | |
263 | #endif | |
264 |