Репозитории ALT
S: | 1.10.2-alt1 |
5.1: | 1.4.6-alt0.M51.1 |
4.1: | 1.4.1-alt1 |
4.0: | 1.2.4-alt1 |
3.0: | 1.2.1-alt1 |
Группа :: Система/Библиотеки
Пакет: libgcrypt
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: libgcrypt-1.8.5-vko-salt.patch
Скачать
Скачать
cipher/ecc.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++--
cipher/pubkey-util.c | 23 ++++++++++++++++-
src/cipher.h | 2 +-
3 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 3f221a2..ce4db8f 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -1264,6 +1264,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
gcry_mpi_t mpi_s = NULL;
gcry_mpi_t mpi_e = NULL;
gcry_mpi_t data = NULL;
+ gcry_mpi_t salt = NULL;
ECC_public_key pk;
mpi_ec_t ec = NULL;
int flags = 0;
@@ -1345,6 +1346,29 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
mpi_clear_bit (data, i);
mpi_set_highbit (data, mpi_get_nbits (pk.E.p) - 1);
}
+
+ /* For GOST extract the UKM value. If its length is unspecified
+ take 64 bits as default. */
+ if ((flags & PUBKEY_FLAG_GOST))
+ {
+ unsigned int ukm_blen = ctx.saltlen ? ctx.saltlen : 64;
+ if (_gcry_mpi_get_nbits (data) < ukm_blen)
+ {
+ rc = GPG_ERR_TOO_SHORT;
+ goto leave;
+ }
+ salt = _gcry_mpi_copy (data);
+ if (!salt)
+ {
+ rc = gpg_error_from_syserror ();
+ goto leave;
+ }
+ _gcry_mpi_clear_highbit (salt, ukm_blen);
+ if (DBG_CIPHER)
+ log_printmpi ("UKM: ", salt);
+ _gcry_mpi_rshift (data, data, ukm_blen);
+ }
+
if (DBG_CIPHER)
log_mpidump ("ecc_encrypt data", data);
@@ -1404,6 +1428,10 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
/* R = kQ <=> R = kdG */
_gcry_mpi_ec_mul_point (&R, data, &pk.Q, ec);
+ /* Multiply the resulting point by a salt value if any. */
+ if (salt)
+ _gcry_mpi_ec_mul_point (&R, salt, &R, ec);
+
if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
{
/*
@@ -1471,7 +1499,14 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
}
if (!rc)
- rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
+ {
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("ecc_encrypt res", mpi_s);
+ log_printmpi ("ecc_encrypt public key e", mpi_e);
+ }
+ rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
+ }
leave:
_gcry_mpi_release (pk.E.p);
@@ -1490,6 +1525,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
sexp_release (l1);
_gcry_mpi_ec_free (ec);
_gcry_pk_util_free_encoding_ctx (&ctx);
+ _gcry_mpi_release (salt);
if (DBG_CIPHER)
log_debug ("ecc_encrypt => %s\n", gpg_strerror (rc));
return rc;
@@ -1518,6 +1554,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
mpi_point_struct kG;
mpi_point_struct R;
gcry_mpi_t r = NULL;
+ gcry_mpi_t salt = NULL;
int flags = 0;
memset (&sk, 0, sizeof sk);
@@ -1613,10 +1650,35 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
goto leave;
}
-
ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, flags,
sk.E.p, sk.E.a, sk.E.b);
+ /* For GOST extract the UKM value. */
+ if ((flags & PUBKEY_FLAG_GOST) || 0 == strncmp ("GOST", sk.E.name, 4))
+ {
+ // FIXME: Expect an uncompressed point format 0x04...
+ int key_len = 2*nbits/8 + 1;
+ int data_len = (_gcry_mpi_get_nbits (data_e)+7)/8;
+ int ukm_blen = (data_len - key_len) * 8;
+ if (ukm_blen < 64)
+ {
+ rc = GPG_ERR_TOO_SHORT;
+ goto leave;
+ }
+ salt = _gcry_mpi_copy (data_e);
+ if (!salt)
+ {
+ rc = gpg_error_from_syserror ();
+ goto leave;
+ }
+ _gcry_mpi_clear_highbit (salt, ukm_blen);
+ if (DBG_CIPHER)
+ log_printmpi ("UKM: ", salt);
+ _gcry_mpi_rshift (data_e, data_e, ukm_blen);
+ if (DBG_CIPHER)
+ log_printmpi ("ecc_decrypt d_e", data_e);
+ }
+
/*
* Compute the plaintext.
*/
@@ -1630,6 +1692,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
if (DBG_CIPHER)
log_printpnt ("ecc_decrypt kG", &kG, NULL);
+
if ((flags & PUBKEY_FLAG_DJB_TWEAK))
{
/* For X25519, by its definition, validation should not be done. */
@@ -1651,9 +1714,14 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
goto leave;
}
+
/* R = dkG */
_gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec);
+ /* Multiply the resulting point by a salt value if any. */
+ if (salt)
+ _gcry_mpi_ec_mul_point (&R, salt, &R, ec);
+
/* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */
{
gcry_mpi_t x, y;
@@ -1743,6 +1811,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
sexp_release (l1);
_gcry_mpi_ec_free (ec);
_gcry_pk_util_free_encoding_ctx (&ctx);
+ _gcry_mpi_release (salt);
if (DBG_CIPHER)
log_debug ("ecc_decrypt => %s\n", gpg_strerror (rc));
return rc;
diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c
index c40ef97..66278b6 100644
--- a/cipher/pubkey-util.c
+++ b/cipher/pubkey-util.c
@@ -649,7 +649,7 @@ _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
(<mpi>)
or
(data
- [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
+ [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa, gost])]
[(hash <algo> <value>)]
[(value <text>)]
[(hash-algo <algo>)]
@@ -666,6 +666,7 @@ _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
LABEL is specific to OAEP.
SALT-LENGTH is for PSS it is limited to 16384 bytes.
+ For GOST a SALT-LENGTH means the length of UKM in bits.
RANDOM-OVERRIDE is used to replace random nonces for regression
testing. */
@@ -812,6 +813,26 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
*ret_mpi = sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
if (!*ret_mpi)
rc = GPG_ERR_INV_OBJ;
+
+ if (parsed_flags & PUBKEY_FLAG_GOST)
+ {
+ gcry_sexp_t list;
+ /* Get SALT-LENGTH (UKM length). */
+ list = sexp_find_token (ldata, "salt-length", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+ ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
+ sexp_release (list);
+ }
+ else
+ ctx->saltlen = 0;
+ }
}
else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
&& ctx->op == PUBKEY_OP_ENCRYPT)
diff --git a/src/cipher.h b/src/cipher.h
index f2acb55..197dabc 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -76,7 +76,7 @@ struct pk_encoding_ctx
unsigned char *label;
size_t labellen;
- /* for PSS */
+ /* for PSS or GOST (UKM length in bits)*/
size_t saltlen;
int (* verify_cmp) (void *opaque, gcry_mpi_t tmp);