1238384SjkimGOST ENGINE
2238384Sjkim
3238384SjkimThis engine provides implementation of Russian cryptography standard.
4238384SjkimThis is also an example of adding new cryptoalgorithms into OpenSSL
5238384Sjkimwithout changing its core. If OpenSSL is compiled with dynamic engine
6238384Sjkimsupport, new algorithms can be added even without recompilation of
7238384SjkimOpenSSL and applications which use it.
8238384Sjkim
9238384SjkimALGORITHMS SUPPORTED
10238384Sjkim
11238384SjkimGOST R 34.10-94 and GOST R 34.10-2001 - digital signature algorithms.
12238384Sjkim   Also support key exchange based on public keys. See RFC 4357 for
13238384Sjkim   details of VKO key exchange algorithm. These algorithms use
14238384Sjkim   256 bit private keys. Public keys are 1024 bit for 94 and 512 bit for
15238384Sjkim   2001 (which is elliptic-curve based). Key exchange algorithms
16238384Sjkim   (VKO R 34.10) are supported on these keys too.
17238384Sjkim   
18238384SjkimGOST R 34.11-94  Message digest algorithm. 256-bit hash value
19238384Sjkim
20238384SjkimGOST 28147-89 - Symmetric cipher  with 256-bit key. Various modes are
21238384Sjkim   defined in the standard, but only CFB and CNT modes are implemented
22238384Sjkim   in the engine. To make statistical analysis more difficult, key
23238384Sjkim   meshing is supported (see RFC 4357).
24238384Sjkim
25238384SjkimGOST 28147-89 MAC mode. Message authentication code. While most MAC
26238384Sjkim    algorithms  out there are based on hash functions using HMAC
27238384Sjkim	algorithm, this algoritm is based on symmetric cipher. 
28238384Sjkim	It has 256-bit symmetric key and only 32 bits of MAC value
29238384Sjkim	(while HMAC has same key size and value size). 
30238384Sjkim
31238384Sjkim	It is implemented as combination of EVP_PKEY type and EVP_MD type.
32238384Sjkim
33238384SjkimUSAGE OF THESE ALGORITHMS
34238384Sjkim
35238384SjkimThis engine is designed to allow usage of this algorithms in the
36238384Sjkimhigh-level openssl functions, such as PKI, S/MIME and TLS.
37238384Sjkim
38238384SjkimSee RFC 4490 for S/MIME with GOST algorithms and RFC 4491 for PKI.
39238384SjkimTLS support is implemented according IETF
40238384Sjkimdraft-chudov-cryptopro-cptls-03.txt and is compatible with
41238384SjkimCryptoPro CSP 3.0 and 3.6 as well as with MagPro CSP. 
42238384SjkimGOST ciphersuites implemented in CryptoPro CSP 2.0 are not supported
43238384Sjkimbecause they use ciphersuite numbers used now by AES ciphersuites.
44238384Sjkim
45238384SjkimTo use the engine you have to load it via openssl configuration
46238384Sjkimfile. Applications should read openssl configuration file or provide
47238384Sjkimtheir own means to load engines. Also, applications which operate with
48238384Sjkimprivate keys, should use generic EVP_PKEY API instead of using RSA or
49238384Sjkimother algorithm-specific API.
50238384Sjkim
51238384SjkimCONFIGURATION FILE
52238384Sjkim
53238384SjkimConfiguration file should include following statement in the global
54238384Sjkimsection, i.e. before first bracketed section header (see config(5) for details)
55238384Sjkim
56238384Sjkim   openssl_conf = openssl_def
57238384Sjkim
58238384Sjkimwhere openssl_def is name of the section in configuration file which
59238384Sjkimdescribes global defaults.
60238384Sjkim
61238384SjkimThis section should contain following statement:
62238384Sjkim
63238384Sjkim   [openssl_def]
64238384Sjkim   engines = engine_section
65238384Sjkim
66238384Sjkimwhich points to the section which describes list of the engines to be
67238384Sjkimloaded. This section should contain:
68238384Sjkim
69238384Sjkim	[engine_section]
70238384Sjkim	gost = gost_section
71238384Sjkim
72238384SjkimAnd section which describes configuration of the engine should contain
73238384Sjkim
74238384Sjkim	[gost_section]
75238384Sjkim	engine_id = gost
76238384Sjkim	dynamic_path = /usr/lib/ssl/engines/libgost.so
77238384Sjkim	default_algorithms = ALL
78238384Sjkim	CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet
79238384Sjkim
80238384SjkimWhere engine_id parameter specifies name of engine (should be "gost").
81238384Sjkimdynamic_path is a location of the loadable shared library implementing the
82238384Sjkimengine. If the engine is compiled statically or is located in the OpenSSL
83238384Sjkimengines directory, this line can be omitted. 
84238384Sjkimdefault_algorithms parameter specifies that all algorithms, provided by
85238384Sjkimengine, should be used.
86238384Sjkim
87238384SjkimThe CRYPT_PARAMS parameter is engine-specific. It allows the user to choose
88238384Sjkimbetween different parameter sets of symmetric cipher algorithm. RFC 4357
89238384Sjkimspecifies several parameters for the GOST 28147-89 algorithm, but OpenSSL
90238384Sjkimdoesn't provide user interface to choose one when encrypting. So use engine
91238384Sjkimconfiguration parameter instead.
92238384Sjkim
93238384SjkimValue of this parameter can be either short name, defined in OpenSSL
94238384Sjkimobj_dat.h header file or numeric representation of OID, defined in RFC
95238384Sjkim4357. 
96238384Sjkim
97238384SjkimUSAGE WITH COMMAND LINE openssl UTILITY
98238384Sjkim
99238384Sjkim1. Generation of private key
100238384Sjkim
101238384Sjkim	openssl genpkey -algorithm gost2001 -pkeyopt paramset:A -out seckey.pem
102238384Sjkim
103238384Sjkim  Use -algorithm option to specify algorithm.
104238384Sjkim  Use -pkeyopt option to pass paramset to algorithm. The following paramsets
105238384Sjkim  are supported by 
106238384Sjkim  	gost94: 0,A,B,C,D,XA,XB,XC
107238384Sjkim	gost2001: 0,A,B,C,XA,XB
108238384Sjkim  You can also use numeric representation of OID as to destinate
109238384Sjkim  paramset.
110238384Sjkim
111238384Sjkim  Paramsets starting with X are intended to use for key exchange keys.
112238384Sjkim  Paramsets without X are for digital signature keys.
113238384Sjkim
114238384Sjkim  Paramset for both algorithms 0 is the test paramset which should be used
115238384Sjkim  only for test purposes.
116238384Sjkim
117238384SjkimThere are no algorithm-specific things with generation of certificate
118238384Sjkimrequest once you have a private key.
119238384Sjkim
120238384Sjkim2. Generation of certificate request along with private/public keypar
121238384Sjkim
122238384Sjkim   openssl req -newkey gost2001 -pkeyopt paramset:A
123238384Sjkim
124238384Sjkim   Syntax of -pkeyopt parameter is identical with genpkey command.
125238384Sjkim
126238384Sjkim   You can also use oldstyle syntax -newkey gost2001:paramfile, but in
127238384Sjkim   this case you should create parameter file first. 
128238384Sjkim
129238384Sjkim   It can be created with
130238384Sjkim
131238384Sjkim   openssl genpkey -genparam -algorithm gost2001 -pkeyopt paramset:A\
132238384Sjkim      -out paramfile.
133238384Sjkim
134238384Sjkim3. S/MIME operations
135238384Sjkim
136238384SjkimIf you want to send encrypted mail using GOST algorithms, don't forget
137238384Sjkimto specify -gost89 as encryption algorithm for OpenSSL smime command.
138238384SjkimWhile OpenSSL is clever enough to find out that GOST R 34.11-94 digest
139238384Sjkimmust be used for digital signing with GOST private key, it have no way
140238384Sjkimto derive symmetric encryption algorithm from key exchange keys.
141238384Sjkim
142238384Sjkim4. TLS operations
143238384Sjkim
144238384SjkimOpenSSL supports all four ciphersuites defined in the IETF draft.
145238384SjkimOnce you've loaded GOST key and certificate into your TLS server,
146238384Sjkimciphersuites which use GOST 28147-89 encryption are enabled.
147238384Sjkim
148238384SjkimCiphersuites with NULL encryption should be enabled explicitely if
149238384Sjkimneeded.
150238384Sjkim
151238384SjkimGOST2001-GOST89-GOST89 Uses GOST R 34.10-2001 for auth and key exchange
152238384Sjkim		GOST 28147-89 for encryption and GOST 28147-89 MAC
153238384SjkimGOST94-GOST89-GOST89 Uses GOST R 34.10-94 for auth and key exchange
154238384Sjkim		GOST 28147-89 for encryption and GOST 28147-89 MAC
155238384SjkimGOST2001-NULL-GOST94 Uses GOST R 34.10-2001 for auth and key exchange,
156238384Sjkim        no encryption and HMAC, based on GOST R 34.11-94
157238384SjkimGOST94-NULL-GOST94 Uses GOST R 34.10-94 for auth and key exchange,
158238384Sjkim        no encryption and HMAC, based on GOST R 34.11-94
159238384Sjkim
160238384SjkimGost 94 and gost 2001 keys can be used simultaneously in the TLS server.
161238384SjkimRSA, DSA and EC keys can be used simultaneously with GOST keys, if
162238384Sjkimserver implementation supports loading more than two private
163238384Sjkimkey/certificate pairs. In this case ciphersuites which use any of loaded
164238384Sjkimkeys would be supported and clients can negotiate ones they wish.
165238384Sjkim
166238384SjkimThis allows creation of TLS servers which use GOST ciphersuites for
167238384SjkimRussian clients and RSA/DSA ciphersuites for foreign clients.
168238384Sjkim
169238384Sjkim5. Calculation of digests and symmetric encryption
170238384Sjkim OpenSSL provides specific commands (like sha1, aes etc) for calculation
171238384Sjkim of digests and symmetric encryption. Since such commands cannot be
172238384Sjkim added dynamically, no such commands are provided for GOST algorithms.
173238384Sjkim Use generic commands 'dgst' and 'enc'.
174238384Sjkim
175238384Sjkim Calculation of GOST R 34.11-94 message digest
176238384Sjkim
177238384Sjkim openssl dgst -md_gost94 datafile
178238384Sjkim
179238384Sjkim Note that GOST R 34.11-94 specifies that digest value should be
180238384Sjkim interpreted as little-endian number, but OpenSSL outputs just hex dump
181238384Sjkim of digest value.
182238384Sjkim
183238384Sjkim So, to obtain correct digest value, such as produced by gostsum utility
184238384Sjkim included in the engine distribution, bytes of output should be
185238384Sjkim reversed.
186238384Sjkim 
187238384Sjkim Calculation of HMAC based on GOST R 34.11-94
188238384Sjkim
189238384Sjkim openssl dgst -md_gost94 -mac hmac -macopt key:<32 bytes of key> datafile
190238384Sjkim  
191238384Sjkim  (or use hexkey if key contain NUL bytes)
192238384Sjkim Calculation of GOST 28147 MAC
193238384Sjkim
194238384Sjkim openssl dgst -mac gost-mac -macopt key:<32 bytes of key> datafile
195238384Sjkim
196238384Sjkim Note absense of an option that specifies digest algorithm. gost-mac
197238384Sjkim algorithm supports only one digest (which is actually part of
198238384Sjkim implementation of this mac) and OpenSSL is clever enough to find out
199238384Sjkim this.
200238384Sjkim
201238384Sjkim Encryption with GOST 28147 CFB mode
202238384Sjkim openssl enc -gost89 -out encrypted-file -in plain-text-file -k <passphrase>  
203238384Sjkim Encryption with GOST 28147 CNT mode
204238384Sjkim openssl enc -gost89-cnt -out encrypted-file -in plain-text-file -k <passphrase>
205238384Sjkim
206238384Sjkim
207238384Sjkim6. Encrypting private keys and PKCS12
208238384Sjkim
209238384SjkimTo produce PKCS12 files compatible with MagPro CSP, you need to use
210238384SjkimGOST algorithm for encryption of PKCS12 file and also GOST R 34.11-94
211238384Sjkimhash to derive key from password.
212238384Sjkim
213238384Sjkimopenssl pksc12 -export -inkey gost.pem -in gost_cert.pem -keypbe gost89\
214238384Sjkim   -certpbe gost89 -macalg md_gost94
215238384Sjkim 
216238384Sjkim7. Testing speed of symmetric ciphers.
217238384Sjkim   
218238384SjkimTo test performance of GOST symmetric ciphers you should use -evp switch
219238384Sjkimof the openssl speed command. Engine-provided ciphers couldn't be
220238384Sjkimaccessed by cipher-specific functions, only via generic evp interface
221238384Sjkim
222238384Sjkim openssl speed -evp gost89
223238384Sjkim openssl speed -evp gost89-cnt
224238384Sjkim
225238384Sjkim
226238384SjkimPROGRAMMING INTERFACES DETAILS
227238384Sjkim
228238384SjkimApplications never should access engine directly. They only use provided
229238384SjkimEVP_PKEY API. But there are some details, which should be taken into
230238384Sjkimaccount.
231238384Sjkim
232238384SjkimEVP provides two kinds of API for key exchange:
233238384Sjkim
234238384Sjkim1. EVP_PKEY_encrypt/EVP_PKEY_decrypt functions, intended to use with
235238384Sjkim	RSA-like public key encryption algorithms
236238384Sjkim
237238384Sjkim2. EVP_PKEY_derive, intended to use with Diffie-Hellman-like shared key
238238384Sjkimcomputing algorithms.
239238384Sjkim
240238384SjkimAlthough VKO R 34.10 algorithms, described in the RFC 4357 are
241238384Sjkimdefinitely second case, engine provides BOTH API for GOST R 34.10 keys.
242238384Sjkim
243238384SjkimEVP_PKEY_derive just invokes appropriate VKO algorithm and computes
244238384Sjkim256 bit shared key. VKO R 34.10-2001 requires 64 bits of random user key
245238384Sjkimmaterial (UKM). This UKM should be transmitted to other party, so it is
246238384Sjkimnot generated inside derive function.
247238384Sjkim
248238384SjkimIt should be set by EVP_PKEY_CTX_ctrl function using
249238384SjkimEVP_PKEY_CTRL_SET_IV command after call of EVP_PKEY_derive_init, but
250238384Sjkimbefore EVP_PKEY_derive.
251238384Sjkim	unsigned char ukm[8];
252238384Sjkim	RAND_bytes(ukm,8);
253238384Sjkim   EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, 8, ukm)
254238384Sjkim
255238384SjkimEVP_PKEY_encrypt encrypts provided session key with VKO shared key and
256238384Sjkimpacks it into GOST key transport structure, described in the RFC 4490.
257238384Sjkim
258238384SjkimIt typically uses ephemeral key pair to compute shared key and packs its
259238384Sjkimpublic part along with encrypted key. So, for most cases use of 
260238384SjkimEVP_PKEY_encrypt/EVP_PKEY_decrypt with GOST keys is almost same as with
261238384SjkimRSA.
262238384Sjkim
263238384SjkimHowever, if peerkey field in the EVP_PKEY_CTX structure is set (using
264238384SjkimEVP_PKEY_derive_set_peerkey function) to EVP_PKEY structure which has private
265238384Sjkimkey and uses same parameters as the public key from which this EVP_PKEY_CTX is
266238384Sjkimcreated, EVP_PKEY_encrypt will use this private key to compute shared key and
267238384Sjkimset ephemeral key in the GOST_key_transport structure to NULL. In this case
268238384Sjkimpkey and peerkey fields in the EVP_PKEY_CTX are used upside-down.
269238384Sjkim
270238384SjkimIf EVP_PKEY_decrypt encounters GOST_key_transport structure with NULL
271238384Sjkimpublic key field, it tries to use peerkey field from the context to
272238384Sjkimcompute shared key. In this case peerkey field should really contain
273238384Sjkimpeer public key.
274238384Sjkim
275238384SjkimEncrypt operation supports EVP_PKEY_CTRL_SET_IV operation as well.
276238384SjkimIt can be used when some specific restriction on UKM are imposed by
277238384Sjkimhigher level protocol. For instance, description of GOST ciphersuites
278238384Sjkimrequires UKM to be derived from shared secret. 
279238384Sjkim
280238384SjkimIf UKM is not set by this control command, encrypt operation would
281238384Sjkimgenerate random UKM.
282238384Sjkim
283238384Sjkim
284238384SjkimThis sources include implementation of GOST 28147-89 and GOST R 34.11-94
285238384Sjkimwhich are completely indepentent from OpenSSL and can be used separately
286238384Sjkim(files gost89.c, gost89.h, gosthash.c, gosthash.h) Utility gostsum (file
287238384Sjkimgostsum.c) is provided as example of such separate usage. This is
288238384Sjkimprogram, simular to md5sum and sha1sum utilities, but calculates GOST R
289238384Sjkim34.11-94 hash.
290238384Sjkim
291238384SjkimMakefile doesn't include rule for compiling gostsum.
292238384SjkimUse command
293238384Sjkim
294238384Sjkim$(CC) -o gostsum gostsum.c gost89.c gosthash.c
295238384Sjkimwhere $(CC) is name of your C compiler.
296238384Sjkim
297238384SjkimImplementations of GOST R 34.10-xx, including VKO algorithms heavily
298238384Sjkimdepends on OpenSSL BIGNUM and Elliptic Curve libraries.
299238384Sjkim
300238384Sjkim
301