267 lines
11 KiB
Text
267 lines
11 KiB
Text
OPENSSL GOST ENGINE
|
||
|
||
An implementation of Russian cryptography standards for OpenSSL.
|
||
|
||
Since v.0.9.6 OpenSSL provides facilities for creating external dynamically
|
||
loaded cryptographic engines (OpenSSL should be built with dynamic engine
|
||
support to be able to use it). Since v 1.0 it became possible to provide
|
||
digital signature algorithms via engines.
|
||
|
||
This engine provides an implementation of various Russian cryptographic
|
||
algorithms, known generally as GOST cryptographic algorithms (see detailed list
|
||
below). These algorithms can be used both via OpenSSL command line tools and
|
||
via high-level libopenssl calls.
|
||
|
||
OpenSSL GOST Engine also includes 'gostsum' and 'gost12sum' command line tools
|
||
for generating and checking GOST R34.11-94 and GOST R34.11-2012 hashsums.
|
||
They have the same purposes and behavior as the well-known sha1sum and md5sum
|
||
utilities. These utilities can be used independently from OpenSSL.
|
||
|
||
ALGORITHMS SUPPORTED
|
||
|
||
GOST R 34.10-2001 and GOST R 34.10-2012 - digital signature algorithms.
|
||
Also support key exchange based on public keys. See RFC 4357 for
|
||
details of VKO key exchange algorithm. These algorithms use
|
||
256 bit private keys for GOST 2001, 256/512 bits for GOST 2012.
|
||
Public keys are 512 bit for GOST 2001 and 512/1024 for GOST 2012.
|
||
Key exchange algorithms (VKO R 34.10) are supported on these keys too.
|
||
|
||
GOST R 34.11-94 Message digest algorithm. 256-bit hash value.
|
||
|
||
GOST R 34.11-2012 Message digest algorithm. 256- and 512-bit hash values.
|
||
|
||
GOST 28147-89 - Symmetric cipher with 256-bit key. Various modes are
|
||
defined in the standard, but only CBC, CFB and CNT modes are implemented
|
||
in the engine. To make statistical analysis more difficult, key
|
||
meshing is supported (see RFC 4357).
|
||
|
||
GOST 28147-89 MAC mode. Message authentication code. While a lot of MAC
|
||
algorithms out there are based on hash functions using HMAC algorithm,
|
||
this algoritm is based on symmetric cipher.
|
||
It has 256-bit symmetric key and 8-64 (default 32) bits of MAC value
|
||
(while HMAC has same key size and value size).
|
||
It is implemented as combination of EVP_PKEY type and EVP_MD type.
|
||
|
||
GOST R 34.13–2015 - Symmetric cypher Grasshopper ("Kuznechik")
|
||
|
||
USAGE OF GOST ALGORITHMS
|
||
|
||
This engine is designed to allow usage of this algorithms in the high-level
|
||
openssl functions, such as PKI, S/MIME and TLS. All the necessary constants are
|
||
added to the main source tree of OpenSSL.
|
||
|
||
See RFC 4490 for S/MIME with GOST algorithms and RFC 4491 for PKI. TLS support
|
||
is implemented according IETF draft-chudov-cryptopro-cptls-03.txt and is
|
||
compatible with CryptoPro CSP 3.0+.
|
||
|
||
To use the engine you have to load it via openssl configuration
|
||
file. Applications should read openssl configuration file or provide
|
||
their own means to load engines. Also, applications which operate with
|
||
private keys, should use generic EVP_PKEY API instead of using RSA or
|
||
other algorithm-specific API.
|
||
|
||
USAGE WITH COMMAND LINE openssl UTILITY
|
||
|
||
1. Generation of private key
|
||
|
||
openssl genpkey -algorithm gost2001 -pkeyopt paramset:A -out seckey.pem
|
||
|
||
Use -algorithm option to specify algorithm.
|
||
Use -pkeyopt option to pass paramset to algorithm. The following paramsets
|
||
are supported by
|
||
gost2001: 0,A,B,C,XA,XB
|
||
gost2012_256: 0,A,B,C,XA,XB,TCA,TCB,TCC,TCD
|
||
gost2012_512: A,B,C
|
||
You can also use numeric representation of OID as to destinate
|
||
paramset.
|
||
|
||
Paramsets starting with X are intended to use for key exchange keys.
|
||
Paramsets without X are for digital signature keys.
|
||
|
||
Paramset for both algorithms 0 is the test paramset which should be used
|
||
only for test purposes.
|
||
|
||
There are no algorithm-specific things with generation of certificate
|
||
request once you have a private key.
|
||
|
||
2. Generation of certificate request along with private/public keypar
|
||
|
||
openssl req -newkey gost2001 -pkeyopt paramset:A
|
||
|
||
Syntax of -pkeyopt parameter is identical with genpkey command.
|
||
|
||
You can also use oldstyle syntax -newkey gost2001:paramfile, but in
|
||
this case you should create parameter file first.
|
||
|
||
It can be created with
|
||
|
||
openssl genpkey -genparam -algorithm gost2001 -pkeyopt paramset:A\
|
||
-out paramfile.
|
||
|
||
3. S/MIME operations
|
||
|
||
If you want to send encrypted mail using GOST algorithms, don't forget
|
||
to specify -gost89 as encryption algorithm for OpenSSL smime command.
|
||
While OpenSSL is clever enough to find out that GOST R 34.11-94 digest
|
||
must be used for digital signing with GOST private key, it have no way
|
||
to derive symmetric encryption algorithm from key exchange keys.
|
||
|
||
4. TLS operations
|
||
|
||
OpenSSL supports all four ciphersuites defined in the IETF draft.
|
||
Once you've loaded GOST key and certificate into your TLS server,
|
||
ciphersuites which use GOST 28147-89 encryption are enabled.
|
||
|
||
Ciphersuites with NULL encryption should be enabled explicitely if
|
||
needed.
|
||
|
||
GOST2001-GOST89-GOST89 Uses GOST R 34.10-2001 for auth and key exchange,
|
||
GOST 28147-89 for encryption and GOST 28147-89 MAC
|
||
GOST2001-NULL-GOST94 Uses GOST R 34.10-2001 for auth and key exchange,
|
||
no encryption and HMAC, based on GOST R 34.11-94
|
||
GOST2012-GOST8912-GOST8912 Uses GOST R 34.10-2001 or 2012 for auth and key exchange,
|
||
GOST 28147-89 with paramset Z for encryption and GOST 28147-89 MAC with paramset Z
|
||
GOST2012-NULL-GOST1 Uses GOST R 34.10-2001 or 2012 for auth and key exchange,
|
||
no encryption and HMAC, based on GOST R 34.11-2012 256-bit.
|
||
|
||
RSA, DSA and EC keys can be used simultaneously with GOST keys, if
|
||
server implementation supports loading more than two private
|
||
key/certificate pairs. In this case ciphersuites which use any of loaded
|
||
keys would be supported and clients can negotiate ones they wish.
|
||
|
||
This allows creation of TLS servers which use GOST ciphersuites for
|
||
Russian clients and RSA/DSA ciphersuites for foreign clients.
|
||
|
||
5. Calculation of digests and symmetric encryption
|
||
OpenSSL provides specific commands (like sha1, aes etc) for calculation
|
||
of digests and symmetric encryption. Since such commands cannot be
|
||
added dynamically, no such commands are provided for GOST algorithms.
|
||
Use generic commands 'dgst' and 'enc'.
|
||
|
||
Calculation of GOST R 34.11-94 message digest
|
||
|
||
openssl dgst -md_gost94 datafile
|
||
|
||
Note that GOST R 34.11-94 specifies that digest value should be
|
||
interpreted as little-endian number, but OpenSSL outputs just hex dump
|
||
of digest value.
|
||
|
||
So, to obtain correct digest value, such as produced by gostsum utility
|
||
included in the engine distribution, bytes of output should be
|
||
reversed.
|
||
|
||
Calculation of HMAC based on GOST R 34.11-94
|
||
|
||
openssl dgst -md_gost94 -hmac <32 bytes of key> datafile
|
||
|
||
(or use hexkey if key contain NUL bytes)
|
||
Calculation of GOST 28147 MAC
|
||
|
||
openssl dgst -mac gost-mac -macopt key:<32 bytes of key> datafile
|
||
|
||
Note absence of an option that specifies digest algorithm. gost-mac
|
||
algorithm supports only one digest (which is actually part of
|
||
implementation of this mac) and OpenSSL is clever enough to find out
|
||
this.
|
||
|
||
Following mac options are supported:
|
||
|
||
key:(32 bytes of key)
|
||
|
||
hexkey:(64 hexadecimal digits of key)
|
||
|
||
Engine support calculation of mac with size different from default 32
|
||
bits. You can set mac size to any value from 1 to 8 bytes using
|
||
|
||
-sigopt size:(number from 1 to 8 - mac size in bytes)
|
||
|
||
(dgst command uses different EVP_PKEY_CTX for initialization and for
|
||
finalization of MAC. Option of first are set via -macopt, and for
|
||
second via -sigopt. Key should be set during initialization and size
|
||
during finalization. If you use API functions
|
||
EVP_DigestSignInit/EVP_DigestSignFinal, you can set both options at
|
||
the same time).
|
||
|
||
Encryption with GOST 28147 CFB mode
|
||
openssl enc -gost89 -out encrypted-file -in plain-text-file -k <passphrase>
|
||
Encryption with GOST 28147 CNT mode
|
||
openssl enc -gost89-cnt -out encrypted-file -in plain-text-file -k <passphrase>
|
||
Encryption with GOST 28147 CBC mode
|
||
openssl enc -gost89-cbc -out encrypted-file -in plain-text-file -k <passphrase>
|
||
|
||
6. Encrypting private keys and PKCS12
|
||
|
||
To produce PKCS12 files compatible with MagPro CSP, you need to use
|
||
GOST algorithm for encryption of PKCS12 file and also GOST R 34.11-94
|
||
hash to derive key from password.
|
||
|
||
openssl pksc12 -export -inkey gost.pem -in gost_cert.pem -keypbe gost89\
|
||
-certpbe gost89 -macalg md_gost94
|
||
|
||
7. Testing speed of symmetric ciphers.
|
||
|
||
To test performance of GOST symmetric ciphers you should use -evp switch
|
||
of the openssl speed command. Engine-provided ciphers couldn't be
|
||
accessed by cipher-specific functions, only via generic evp interface
|
||
|
||
openssl speed -evp gost89
|
||
openssl speed -evp gost89-cnt
|
||
openssl speed -evp gost89-cbc
|
||
|
||
|
||
PROGRAMMING INTERFACES DETAILS
|
||
|
||
Applications never should access engine directly. They only use provided
|
||
EVP_PKEY API. But there are some details, which should be taken into
|
||
account.
|
||
|
||
EVP provides two kinds of API for key exchange:
|
||
|
||
1. EVP_PKEY_encrypt/EVP_PKEY_decrypt functions, intended to use with
|
||
RSA-like public key encryption algorithms
|
||
|
||
2. EVP_PKEY_derive, intended to use with Diffie-Hellman-like shared key
|
||
computing algorithms.
|
||
|
||
Although VKO R 34.10 algorithms, described in the RFC 4357 are
|
||
definitely second case, engine provides BOTH API for GOST R 34.10 keys.
|
||
|
||
EVP_PKEY_derive just invokes appropriate VKO algorithm and computes
|
||
256 bit shared key. VKO R 34.10-2001 requires 64 bits of random user key
|
||
material (UKM). This UKM should be transmitted to other party, so it is
|
||
not generated inside derive function.
|
||
|
||
It should be set by EVP_PKEY_CTX_ctrl function using
|
||
EVP_PKEY_CTRL_SET_IV command after call of EVP_PKEY_derive_init, but
|
||
before EVP_PKEY_derive.
|
||
unsigned char ukm[8];
|
||
RAND_bytes(ukm,8);
|
||
EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, 8, ukm)
|
||
|
||
EVP_PKEY_encrypt encrypts provided session key with VKO shared key and
|
||
packs it into GOST key transport structure, described in the RFC 4490.
|
||
|
||
It typically uses ephemeral key pair to compute shared key and packs its
|
||
public part along with encrypted key. So, for most cases use of
|
||
EVP_PKEY_encrypt/EVP_PKEY_decrypt with GOST keys is almost same as with
|
||
RSA.
|
||
|
||
However, if peerkey field in the EVP_PKEY_CTX structure is set (using
|
||
EVP_PKEY_derive_set_peerkey function) to EVP_PKEY structure which has private
|
||
key and uses same parameters as the public key from which this EVP_PKEY_CTX is
|
||
created, EVP_PKEY_encrypt will use this private key to compute shared key and
|
||
set ephemeral key in the GOST_key_transport structure to NULL. In this case
|
||
pkey and peerkey fields in the EVP_PKEY_CTX are used upside-down.
|
||
|
||
If EVP_PKEY_decrypt encounters GOST_key_transport structure with NULL
|
||
public key field, it tries to use peerkey field from the context to
|
||
compute shared key. In this case peerkey field should really contain
|
||
peer public key.
|
||
|
||
Encrypt operation supports EVP_PKEY_CTRL_SET_IV operation as well.
|
||
It can be used when some specific restriction on UKM are imposed by
|
||
higher level protocol. For instance, description of GOST ciphersuites
|
||
requires UKM to be derived from shared secret.
|
||
|
||
If UKM is not set by this control command, encrypt operation would
|
||
generate random UKM.
|