1 /**********************************************************************
3 * Copyright (c) 2005-2006 Cryptocom LTD *
4 * This file is distributed under the same license as OpenSSL *
6 * Main file of GOST engine *
8 * Requires OpenSSL 0.9.9 for compilation *
9 **********************************************************************/
11 #include <openssl/crypto.h>
12 #include <openssl/err.h>
13 #include <openssl/evp.h>
14 #include <openssl/engine.h>
15 #include <openssl/obj_mac.h>
16 #include "e_gost_err.h"
18 static const char *engine_gost_id = "gost";
19 static const char *engine_gost_name =
20 "Reference implementation of GOST engine";
22 static int gost_pkey_meth_nids[] = {
23 NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0
26 /* Symmetric cipher and digest function registrar */
28 static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
29 const int **nids, int nid);
31 static int gost_digests(ENGINE *e, const EVP_MD **digest,
32 const int **nids, int ind);
34 static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
35 const int **nids, int nid);
37 static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
38 const int **nids, int nid);
40 static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 };
42 static int gost_digest_nids(const int **nids)
44 static int digest_nids[3] = { 0, 0, 0 };
50 if ((md = digest_gost()) != NULL)
51 digest_nids[pos++] = EVP_MD_type(md);
52 if ((md = imit_gost_cpa()) != NULL)
53 digest_nids[pos++] = EVP_MD_type(md);
61 static EVP_PKEY_METHOD *pmeth_GostR3410_2001 = NULL;
62 static EVP_PKEY_METHOD *pmeth_Gost28147_MAC = NULL;
64 static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_2001 = NULL;
65 static EVP_PKEY_ASN1_METHOD *ameth_Gost28147_MAC = NULL;
67 static int gost_engine_init(ENGINE *e)
72 static int gost_engine_finish(ENGINE *e)
77 static int gost_engine_destroy(ENGINE *e)
79 digest_gost_destroy();
80 imit_gost_cpa_destroy();
84 pmeth_GostR3410_2001 = NULL;
85 pmeth_Gost28147_MAC = NULL;
86 ameth_GostR3410_2001 = NULL;
87 ameth_Gost28147_MAC = NULL;
91 static int bind_gost(ENGINE *e, const char *id)
94 if (id && strcmp(id, engine_gost_id))
96 if (ameth_GostR3410_2001) {
97 printf("GOST engine already loaded\n");
101 if (!ENGINE_set_id(e, engine_gost_id)) {
102 printf("ENGINE_set_id failed\n");
105 if (!ENGINE_set_name(e, engine_gost_name)) {
106 printf("ENGINE_set_name failed\n");
109 if (!ENGINE_set_digests(e, gost_digests)) {
110 printf("ENGINE_set_digests failed\n");
113 if (!ENGINE_set_ciphers(e, gost_ciphers)) {
114 printf("ENGINE_set_ciphers failed\n");
117 if (!ENGINE_set_pkey_meths(e, gost_pkey_meths)) {
118 printf("ENGINE_set_pkey_meths failed\n");
121 if (!ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) {
122 printf("ENGINE_set_pkey_asn1_meths failed\n");
125 /* Control function and commands */
126 if (!ENGINE_set_cmd_defns(e, gost_cmds)) {
127 fprintf(stderr, "ENGINE_set_cmd_defns failed\n");
130 if (!ENGINE_set_ctrl_function(e, gost_control_func)) {
131 fprintf(stderr, "ENGINE_set_ctrl_func failed\n");
134 if (!ENGINE_set_destroy_function(e, gost_engine_destroy)
135 || !ENGINE_set_init_function(e, gost_engine_init)
136 || !ENGINE_set_finish_function(e, gost_engine_finish)) {
140 if (!register_ameth_gost
141 (NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001",
142 "GOST R 34.10-2001"))
144 if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
145 "GOST-MAC", "GOST 28147-89 MAC"))
148 if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0))
150 if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
152 if (!ENGINE_register_ciphers(e)
153 || !ENGINE_register_digests(e)
154 || !ENGINE_register_pkey_meths(e)
155 /* These two actually should go in LIST_ADD command */
156 || !EVP_add_cipher(&cipher_gost)
157 || !EVP_add_cipher(&cipher_gost_cpacnt)
158 || !EVP_add_digest(digest_gost())
159 || !EVP_add_digest(imit_gost_cpa())
164 ERR_load_GOST_strings();
170 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
171 IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
172 IMPLEMENT_DYNAMIC_CHECK_FN()
173 #endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
174 static int gost_digests(ENGINE *e, const EVP_MD **digest,
175 const int **nids, int nid)
179 return gost_digest_nids(nids);
182 * printf("Digest no %d requested\n",nid);
184 if (nid == NID_id_GostR3411_94) {
185 *digest = digest_gost();
186 } else if (nid == NID_id_Gost28147_89_MAC) {
187 *digest = imit_gost_cpa();
195 static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
196 const int **nids, int nid)
200 *nids = gost_cipher_nids;
201 return 2; /* two ciphers are supported */
204 if (nid == NID_id_Gost28147_89) {
205 *cipher = &cipher_gost;
206 } else if (nid == NID_gost89_cnt) {
207 *cipher = &cipher_gost_cpacnt;
215 static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
216 const int **nids, int nid)
219 *nids = gost_pkey_meth_nids;
224 case NID_id_GostR3410_2001:
225 *pmeth = pmeth_GostR3410_2001;
227 case NID_id_Gost28147_89_MAC:
228 *pmeth = pmeth_Gost28147_MAC;
237 static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
238 const int **nids, int nid)
241 *nids = gost_pkey_meth_nids;
245 case NID_id_GostR3410_2001:
246 *ameth = ameth_GostR3410_2001;
248 case NID_id_Gost28147_89_MAC:
249 *ameth = ameth_Gost28147_MAC;
259 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
260 static ENGINE *engine_gost(void)
262 ENGINE *ret = ENGINE_new();
265 if (!bind_gost(ret, engine_gost_id)) {
272 void ENGINE_load_gost(void)
275 if (pmeth_GostR3410_2001)
277 toadd = engine_gost();