// SPDX-License-Identifier: GPL-2.0+ /* * Elliptic Curve (Russian) Digital Signature Algorithm for Cryptographic API * * Copyright (c) 2019 Vitaly Chikunov <vt@altlinux.org> * * References: * GOST 34.10-2018, GOST R 34.10-2012, RFC 7091, ISO/IEC 14888-3:2018. * * Historical references: * GOST R 34.10-2001, RFC 4357, ISO/IEC 14888-3:2006/Amd 1:2010. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version.
*/
struct ecrdsa_ctx { enum OID algo_oid; /* overall public key oid */ enum OID curve_oid; /* parameter */ enum OID digest_oid; /* parameter */ conststruct ecc_curve *curve; /* curve from oid */ unsignedint digest_len; /* parameter (bytes) */ constchar *digest; /* digest name from oid */ unsignedint key_len; /* @key length (bytes) */ constchar *key; /* raw public key */ struct ecc_point pub_key;
u64 _pubp[2][ECRDSA_MAX_DIGITS]; /* point storage for @pub_key */
};
staticconststruct ecc_curve *get_curve_by_oid(enum OID oid)
{ switch (oid) { case OID_gostCPSignA: case OID_gostTC26Sign256B: return &gost_cp256a; case OID_gostCPSignB: case OID_gostTC26Sign256C: return &gost_cp256b; case OID_gostCPSignC: case OID_gostTC26Sign256D: return &gost_cp256c; case OID_gostTC26Sign512A: return &gost_tc512a; case OID_gostTC26Sign512B: return &gost_tc512b; /* The following two aren't implemented: */ case OID_gostTC26Sign256A: case OID_gostTC26Sign512C: default: return NULL;
}
}
staticint ecrdsa_verify(struct crypto_sig *tfm, constvoid *src, unsignedint slen, constvoid *digest, unsignedint dlen)
{ struct ecrdsa_ctx *ctx = crypto_sig_ctx(tfm); unsignedint ndigits = dlen / sizeof(u64);
u64 r[ECRDSA_MAX_DIGITS]; /* witness (r) */
u64 _r[ECRDSA_MAX_DIGITS]; /* -r */
u64 s[ECRDSA_MAX_DIGITS]; /* second part of sig (s) */
u64 e[ECRDSA_MAX_DIGITS]; /* h \mod q */
u64 *v = e; /* e^{-1} \mod q */
u64 z1[ECRDSA_MAX_DIGITS];
u64 *z2 = _r; struct ecc_point cc = ECC_POINT_INIT(s, e, ndigits); /* reuse s, e */
/* * Digest value, digest algorithm, and curve (modulus) should have the * same length (256 or 512 bits), public key and signature should be * twice bigger.
*/ if (!ctx->curve ||
!ctx->digest ||
!src ||
!digest ||
!ctx->pub_key.x ||
dlen != ctx->digest_len ||
dlen != ctx->curve->g.ndigits * sizeof(u64) ||
ctx->pub_key.ndigits != ctx->curve->g.ndigits ||
dlen * 2 != slen ||
WARN_ON(slen > ECRDSA_MAX_SIG_SIZE) ||
WARN_ON(dlen > STREEBOG512_DIGEST_SIZE)) return -EBADMSG;
/* * Verify doesn't need any output, so it's just informational * for keyctl to determine the key bit size.
*/ return ctx->pub_key.ndigits * sizeof(u64) * BITS_PER_BYTE;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.