Skip to content

Commit 0d7a786

Browse files
vt-altherbertx
authored andcommitted
crypto: ecrdsa - add EC-RDSA (GOST 34.10) algorithm
Add Elliptic Curve Russian Digital Signature Algorithm (GOST R 34.10-2012, RFC 7091, ISO/IEC 14888-3) is one of the Russian (and since 2018 the CIS countries) cryptographic standard algorithms (called GOST algorithms). Only signature verification is supported, with intent to be used in the IMA. Summary of the changes: * crypto/Kconfig: - EC-RDSA is added into Public-key cryptography section. * crypto/Makefile: - ecrdsa objects are added. * crypto/asymmetric_keys/x509_cert_parser.c: - Recognize EC-RDSA and Streebog OIDs. * include/linux/oid_registry.h: - EC-RDSA OIDs are added to the enum. Also, a two currently not implemented curve OIDs are added for possible extension later (to not change numbering and grouping). * crypto/ecc.c: - Kenneth MacKay copyright date is updated to 2014, because vli_mmod_slow, ecc_point_add, ecc_point_mult_shamir are based on his code from micro-ecc. - Functions needed for ecrdsa are EXPORT_SYMBOL'ed. - New functions: vli_is_negative - helper to determine sign of vli; vli_from_be64 - unpack big-endian array into vli (used for a signature); vli_from_le64 - unpack little-endian array into vli (used for a public key); vli_uadd, vli_usub - add/sub u64 value to/from vli (used for increment/decrement); mul_64_64 - optimized to use __int128 where appropriate, this speeds up point multiplication (and as a consequence signature verification) by the factor of 1.5-2; vli_umult - multiply vli by a small value (speeds up point multiplication by another factor of 1.5-2, depending on vli sizes); vli_mmod_special - module reduction for some form of Pseudo-Mersenne primes (used for the curves A); vli_mmod_special2 - module reduction for another form of Pseudo-Mersenne primes (used for the curves B); vli_mmod_barrett - module reduction using pre-computed value (used for the curve C); vli_mmod_slow - more general module reduction which is much slower (used when the modulus is subgroup order); vli_mod_mult_slow - modular multiplication; ecc_point_add - add two points; ecc_point_mult_shamir - add two points multiplied by scalars in one combined multiplication (this gives speed up by another factor 2 in compare to two separate multiplications). ecc_is_pubkey_valid_partial - additional samity check is added. - Updated vli_mmod_fast with non-strict heuristic to call optimal module reduction function depending on the prime value; - All computations for the previously defined (two NIST) curves should not unaffected. * crypto/ecc.h: - Newly exported functions are documented. * crypto/ecrdsa_defs.h - Five curves are defined. * crypto/ecrdsa.c: - Signature verification is implemented. * crypto/ecrdsa_params.asn1, crypto/ecrdsa_pub_key.asn1: - Templates for BER decoder for EC-RDSA parameters and public key. Cc: [email protected] Signed-off-by: Vitaly Chikunov <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 4a2289d commit 0d7a786

File tree

10 files changed

+1022
-13
lines changed

10 files changed

+1022
-13
lines changed

crypto/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,17 @@ config CRYPTO_ECDH
259259
help
260260
Generic implementation of the ECDH algorithm
261261

262+
config CRYPTO_ECRDSA
263+
tristate "EC-RDSA (GOST 34.10) algorithm"
264+
select CRYPTO_ECC
265+
select CRYPTO_AKCIPHER
266+
select CRYPTO_STREEBOG
267+
help
268+
Elliptic Curve Russian Digital Signature Algorithm (GOST R 34.10-2012,
269+
RFC 7091, ISO/IEC 14888-3:2018) is one of the Russian cryptographic
270+
standard algorithms (called GOST algorithms). Only signature verification
271+
is implemented.
272+
262273
comment "Authenticated Encryption with Associated Data"
263274

264275
config CRYPTO_CCM

crypto/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ ecdh_generic-y += ecdh.o
153153
ecdh_generic-y += ecdh_helper.o
154154
obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
155155

156+
$(obj)/ecrdsa_params.asn1.o: $(obj)/ecrdsa_params.asn1.c $(obj)/ecrdsa_params.asn1.h
157+
$(obj)/ecrdsa_pub_key.asn1.o: $(obj)/ecrdsa_pub_key.asn1.c $(obj)/ecrdsa_pub_key.asn1.h
158+
$(obj)/ecrdsa.o: $(obj)/ecrdsa_params.asn1.h $(obj)/ecrdsa_pub_key.asn1.h
159+
ecrdsa_generic-y += ecrdsa.o
160+
ecrdsa_generic-y += ecrdsa_params.asn1.o
161+
ecrdsa_generic-y += ecrdsa_pub_key.asn1.o
162+
obj-$(CONFIG_CRYPTO_ECRDSA) += ecrdsa_generic.o
163+
156164
#
157165
# generic algorithms and the async_tx api
158166
#

crypto/asymmetric_keys/x509_cert_parser.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,26 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
230230
case OID_sha224WithRSAEncryption:
231231
ctx->cert->sig->hash_algo = "sha224";
232232
goto rsa_pkcs1;
233+
234+
case OID_gost2012Signature256:
235+
ctx->cert->sig->hash_algo = "streebog256";
236+
goto ecrdsa;
237+
238+
case OID_gost2012Signature512:
239+
ctx->cert->sig->hash_algo = "streebog512";
240+
goto ecrdsa;
233241
}
234242

235243
rsa_pkcs1:
236244
ctx->cert->sig->pkey_algo = "rsa";
237245
ctx->cert->sig->encoding = "pkcs1";
238246
ctx->algo_oid = ctx->last_oid;
239247
return 0;
248+
ecrdsa:
249+
ctx->cert->sig->pkey_algo = "ecrdsa";
250+
ctx->cert->sig->encoding = "raw";
251+
ctx->algo_oid = ctx->last_oid;
252+
return 0;
240253
}
241254

242255
/*
@@ -256,7 +269,8 @@ int x509_note_signature(void *context, size_t hdrlen,
256269
return -EINVAL;
257270
}
258271

259-
if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0) {
272+
if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
273+
strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0) {
260274
/* Discard the BIT STRING metadata */
261275
if (vlen < 1 || *(const u8 *)value != 0)
262276
return -EBADMSG;
@@ -440,11 +454,15 @@ int x509_extract_key_data(void *context, size_t hdrlen,
440454
{
441455
struct x509_parse_context *ctx = context;
442456

443-
if (ctx->last_oid != OID_rsaEncryption)
457+
ctx->key_algo = ctx->last_oid;
458+
if (ctx->last_oid == OID_rsaEncryption)
459+
ctx->cert->pub->pkey_algo = "rsa";
460+
else if (ctx->last_oid == OID_gost2012PKey256 ||
461+
ctx->last_oid == OID_gost2012PKey512)
462+
ctx->cert->pub->pkey_algo = "ecrdsa";
463+
else
444464
return -ENOPKG;
445465

446-
ctx->cert->pub->pkey_algo = "rsa";
447-
448466
/* Discard the BIT STRING metadata */
449467
if (vlen < 1 || *(const u8 *)value != 0)
450468
return -EBADMSG;

0 commit comments

Comments
 (0)