1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-21 14:47:03 +01:00

start experiment for newer S2K.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2022-02-21 11:22:14 +09:00
parent 05fdaa1737
commit df967c228f
9 changed files with 61 additions and 46 deletions

View File

@ -688,21 +688,21 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
in rfc2440 but the same scheme is used for all other in rfc2440 but the same scheme is used for all other
algorithm identifiers). */ algorithm identifiers). */
iobuf_put (a, 101); iobuf_put (a, 101);
iobuf_put (a, ski->s2k.hash_algo); iobuf_put (a, ski->s2k.u.s.hash_algo);
iobuf_write (a, "GNU", 3 ); iobuf_write (a, "GNU", 3 );
iobuf_put (a, ski->s2k.mode - 1000); iobuf_put (a, ski->s2k.mode - 1000);
} }
else else
{ {
iobuf_put (a, ski->s2k.mode); iobuf_put (a, ski->s2k.mode);
iobuf_put (a, ski->s2k.hash_algo); iobuf_put (a, ski->s2k.u.s.hash_algo);
} }
if (ski->s2k.mode == 1 || ski->s2k.mode == 3) if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
iobuf_write (a, ski->s2k.salt, 8); iobuf_write (a, ski->s2k.u.s.salt, 8);
if (ski->s2k.mode == 3) if (ski->s2k.mode == 3)
iobuf_put (a, ski->s2k.count); iobuf_put (a, ski->s2k.u.s.count);
/* For our special modes 1001, 1002 we do not need an IV. */ /* For our special modes 1001, 1002 we do not need an IV. */
if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002) if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
@ -850,12 +850,12 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
if (enc->version == 5) if (enc->version == 5)
iobuf_put (a, enc->aead_algo); iobuf_put (a, enc->aead_algo);
iobuf_put (a, enc->s2k.mode); iobuf_put (a, enc->s2k.mode);
iobuf_put (a, enc->s2k.hash_algo); iobuf_put (a, enc->s2k.u.s.hash_algo);
if (enc->s2k.mode == 1 || enc->s2k.mode == 3) if (enc->s2k.mode == 1 || enc->s2k.mode == 3)
{ {
iobuf_write (a, enc->s2k.salt, 8); iobuf_write (a, enc->s2k.u.s.salt, 8);
if (enc->s2k.mode == 3) if (enc->s2k.mode == 3)
iobuf_put (a, enc->s2k.count); iobuf_put (a, enc->s2k.u.s.count);
} }
if (enc->seskeylen) if (enc->seskeylen)
iobuf_write (a, enc->seskey, enc->seskeylen); iobuf_write (a, enc->seskey, enc->seskeylen);

View File

@ -569,7 +569,7 @@ setup_symkey (STRING2KEY **symkey_s2k, DEK **symkey_dek)
*symkey_s2k = xmalloc_clear (sizeof **symkey_s2k); *symkey_s2k = xmalloc_clear (sizeof **symkey_s2k);
(*symkey_s2k)->mode = opt.s2k_mode; (*symkey_s2k)->mode = opt.s2k_mode;
(*symkey_s2k)->hash_algo = s2kdigest; (*symkey_s2k)->u.s.hash_algo = s2kdigest;
*symkey_dek = passphrase_to_dek (defcipher, *symkey_dek = passphrase_to_dek (defcipher,
*symkey_s2k, 1, 0, NULL, 0, &canceled); *symkey_s2k, 1, 0, NULL, 0, &canceled);

View File

@ -1175,10 +1175,10 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
ski->sha1chk = 1; ski->sha1chk = 1;
ski->algo = protect_algo; ski->algo = protect_algo;
ski->s2k.mode = s2k_mode; ski->s2k.mode = s2k_mode;
ski->s2k.hash_algo = s2k_algo; ski->s2k.u.s.hash_algo = s2k_algo;
log_assert (sizeof ski->s2k.salt == sizeof s2k_salt); log_assert (sizeof ski->s2k.u.s.salt == sizeof s2k_salt);
memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt); memcpy (ski->s2k.u.s.salt, s2k_salt, sizeof s2k_salt);
ski->s2k.count = s2k_count; ski->s2k.u.s.count = s2k_count;
log_assert (ivlen <= sizeof ski->iv); log_assert (ivlen <= sizeof ski->iv);
memcpy (ski->iv, iv, ivlen); memcpy (ski->iv, iv, ivlen);
ski->ivlen = ivlen; ski->ivlen = ivlen;

View File

@ -2645,7 +2645,7 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
dummy key. We can't express that in an S-expression and dummy key. We can't express that in an S-expression and
thus we send dummy data for the IV. */ thus we send dummy data for the IV. */
snprintf (countbuf, sizeof countbuf, "%lu", snprintf (countbuf, sizeof countbuf, "%lu",
(unsigned long)ski->s2k.count); (unsigned long)ski->s2k.u.s.count);
err = gcry_sexp_build err = gcry_sexp_build
(&prot, NULL, (&prot, NULL,
" (protection %s %s %b %d %s %b %s)\n", " (protection %s %s %b %d %s %b %s)\n",
@ -2654,8 +2654,8 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
ski->ivlen? (int)ski->ivlen:1, ski->ivlen? (int)ski->ivlen:1,
ski->ivlen? ski->iv: (const unsigned char*)"X", ski->ivlen? ski->iv: (const unsigned char*)"X",
ski->s2k.mode, ski->s2k.mode,
openpgp_md_algo_name (ski->s2k.hash_algo), openpgp_md_algo_name (ski->s2k.u.s.hash_algo),
(int)sizeof (ski->s2k.salt), ski->s2k.salt, (int)sizeof (ski->s2k.u.s.salt), ski->s2k.u.s.salt,
countbuf); countbuf);
} }
else else

View File

@ -388,10 +388,10 @@ proc_symkey_enc (CTX c, PACKET *pkt)
s = NULL; /* Force a goto leave. */ s = NULL; /* Force a goto leave. */
} }
if (openpgp_md_test_algo (enc->s2k.hash_algo)) if (openpgp_md_test_algo (enc->s2k.u.s.hash_algo))
{ {
log_error(_("passphrase generated with unknown digest" log_error(_("passphrase generated with unknown digest"
" algorithm %d\n"),enc->s2k.hash_algo); " algorithm %d\n"),enc->s2k.u.s.hash_algo);
s = NULL; s = NULL;
} }
@ -662,7 +662,7 @@ proc_encrypted (CTX c, PACKET *pkt)
{ {
/* If no digest is given we assume SHA-1. */ /* If no digest is given we assume SHA-1. */
s2kbuf.mode = 0; s2kbuf.mode = 0;
s2kbuf.hash_algo = DIGEST_ALGO_SHA1; s2kbuf.u.s.hash_algo = DIGEST_ALGO_SHA1;
s2k = &s2kbuf; s2k = &s2kbuf;
} }
log_info (_("assuming %s encrypted data\n"), "IDEA"); log_info (_("assuming %s encrypted data\n"), "IDEA");

View File

@ -86,14 +86,29 @@ typedef struct {
byte value; byte value;
} prefitem_t; } prefitem_t;
/* A string-to-key specifier as defined in RFC 4880, Section 3.7. */ typedef struct {
typedef struct
{
int mode; /* Must be an integer due to the GNU modes 1001 et al. */
byte hash_algo; byte hash_algo;
byte salt[8]; byte salt[8];
/* The *coded* (i.e., the serialized version) iteration count. */ /* The *coded* (i.e., the serialized version) iteration count. */
u32 count; u32 count;
} S2K_openpgp;
typedef struct {
byte hash_algo;
byte t;
byte m;
byte p;
byte salt[16];
} S2K_argon2;
/* A string-to-key specifier as defined in RFC 4880, Section 3.7. */
typedef struct
{
int mode; /* Must be an integer due to the GNU modes 1001 et al. */
union {
S2K_openpgp s;
S2K_argon2 a;
} u;
} STRING2KEY; } STRING2KEY;
/* A symmetric-key encrypted session key packet as defined in RFC /* A symmetric-key encrypted session key packet as defined in RFC

View File

@ -1275,15 +1275,15 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
k->cipher_algo = cipher_algo; k->cipher_algo = cipher_algo;
k->aead_algo = aead_algo; k->aead_algo = aead_algo;
k->s2k.mode = s2kmode; k->s2k.mode = s2kmode;
k->s2k.hash_algo = hash_algo; k->s2k.u.s.hash_algo = hash_algo;
if (s2kmode == 1 || s2kmode == 3) if (s2kmode == 1 || s2kmode == 3)
{ {
for (i = 0; i < 8 && pktlen; i++, pktlen--) for (i = 0; i < 8 && pktlen; i++, pktlen--)
k->s2k.salt[i] = iobuf_get_noeof (inp); k->s2k.u.s.salt[i] = iobuf_get_noeof (inp);
} }
if (s2kmode == 3) if (s2kmode == 3)
{ {
k->s2k.count = iobuf_get_noeof (inp); k->s2k.u.s.count = iobuf_get_noeof (inp);
pktlen--; pktlen--;
} }
k->seskeylen = seskeylen; k->seskeylen = seskeylen;
@ -1322,11 +1322,11 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
if (s2kmode == 1 || s2kmode == 3) if (s2kmode == 1 || s2kmode == 3)
{ {
es_fprintf (listfp, "\tsalt "); es_fprintf (listfp, "\tsalt ");
es_write_hexstring (listfp, k->s2k.salt, 8, 0, NULL); es_write_hexstring (listfp, k->s2k.u.s.salt, 8, 0, NULL);
if (s2kmode == 3) if (s2kmode == 3)
es_fprintf (listfp, ", count %lu (%lu)", es_fprintf (listfp, ", count %lu (%lu)",
S2K_DECODE_COUNT ((ulong) k->s2k.count), S2K_DECODE_COUNT ((ulong) k->s2k.u.s.count),
(ulong) k->s2k.count); (ulong) k->s2k.u.s.count);
es_fprintf (listfp, "\n"); es_fprintf (listfp, "\n");
} }
} }
@ -2676,7 +2676,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
if (ski->algo) if (ski->algo)
{ {
ski->is_protected = 1; ski->is_protected = 1;
ski->s2k.count = 0; ski->s2k.u.s.count = 0;
if (ski->algo == 254 || ski->algo == 255) if (ski->algo == 254 || ski->algo == 255)
{ {
if (pktlen < 3) if (pktlen < 3)
@ -2693,7 +2693,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
* to delete such a key. */ * to delete such a key. */
ski->s2k.mode = iobuf_get_noeof (inp); ski->s2k.mode = iobuf_get_noeof (inp);
pktlen--; pktlen--;
ski->s2k.hash_algo = iobuf_get_noeof (inp); ski->s2k.u.s.hash_algo = iobuf_get_noeof (inp);
pktlen--; pktlen--;
/* Check for the special GNU extension. */ /* Check for the special GNU extension. */
if (ski->s2k.mode == 101) if (ski->s2k.mode == 101)
@ -2725,7 +2725,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
err = gpg_error (GPG_ERR_INV_PACKET); err = gpg_error (GPG_ERR_INV_PACKET);
goto leave; goto leave;
} }
memcpy (ski->s2k.salt, temp, 8); memcpy (ski->s2k.u.s.salt, temp, 8);
} }
/* Check the mode. */ /* Check the mode. */
@ -2766,11 +2766,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
es_fprintf (listfp, ", algo: %d,%s hash: %d", es_fprintf (listfp, ", algo: %d,%s hash: %d",
ski->algo, ski->algo,
ski->sha1chk ? " SHA1 protection," ski->sha1chk ? " SHA1 protection,"
: " simple checksum,", ski->s2k.hash_algo); : " simple checksum,", ski->s2k.u.s.hash_algo);
if (ski->s2k.mode == 1 || ski->s2k.mode == 3) if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
{ {
es_fprintf (listfp, ", salt: "); es_fprintf (listfp, ", salt: ");
es_write_hexstring (listfp, ski->s2k.salt, 8, 0, NULL); es_write_hexstring (listfp, ski->s2k.u.s.salt, 8, 0, NULL);
} }
es_putc ('\n', listfp); es_putc ('\n', listfp);
} }
@ -2783,12 +2783,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
err = gpg_error (GPG_ERR_INV_PACKET); err = gpg_error (GPG_ERR_INV_PACKET);
goto leave; goto leave;
} }
ski->s2k.count = iobuf_get_noeof (inp); ski->s2k.u.s.count = iobuf_get_noeof (inp);
pktlen--; pktlen--;
if (list_mode) if (list_mode)
es_fprintf (listfp, "\tprotect count: %lu (%lu)\n", es_fprintf (listfp, "\tprotect count: %lu (%lu)\n",
(ulong)S2K_DECODE_COUNT ((ulong)ski->s2k.count), (ulong)S2K_DECODE_COUNT ((ulong)ski->s2k.u.s.count),
(ulong) ski->s2k.count); (ulong) ski->s2k.u.s.count);
} }
else if (ski->s2k.mode == 1002) else if (ski->s2k.mode == 1002)
{ {
@ -2813,10 +2813,10 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
erroring on it here as otherwise there would be no erroring on it here as otherwise there would be no
way to delete such a key. */ way to delete such a key. */
ski->s2k.mode = 0; ski->s2k.mode = 0;
ski->s2k.hash_algo = DIGEST_ALGO_MD5; ski->s2k.u.s.hash_algo = DIGEST_ALGO_MD5;
if (list_mode) if (list_mode)
es_fprintf (listfp, "\tprotect algo: %d (hash algo: %d)\n", es_fprintf (listfp, "\tprotect algo: %d (hash algo: %d)\n",
ski->algo, ski->s2k.hash_algo); ski->algo, ski->s2k.u.s.hash_algo);
} }
/* It is really ugly that we don't know the size /* It is really ugly that we don't know the size

View File

@ -303,14 +303,14 @@ passphrase_to_dek (int cipher_algo, STRING2KEY *s2k,
* Note: This must match the code in encode.c with opt.rfc1991 set */ * Note: This must match the code in encode.c with opt.rfc1991 set */
memset (&help_s2k, 0, sizeof (help_s2k)); memset (&help_s2k, 0, sizeof (help_s2k));
s2k = &help_s2k; s2k = &help_s2k;
s2k->hash_algo = S2K_DIGEST_ALGO; s2k->u.s.hash_algo = S2K_DIGEST_ALGO;
} }
/* Create a new salt or what else to be filled into the s2k for a /* Create a new salt or what else to be filled into the s2k for a
new key. */ new key. */
if (create && (s2k->mode == 1 || s2k->mode == 3)) if (create && (s2k->mode == 1 || s2k->mode == 3))
{ {
gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM); gcry_randomize (s2k->u.s.salt, 8, GCRY_STRONG_RANDOM);
if ( s2k->mode == 3 ) if ( s2k->mode == 3 )
{ {
/* We delay the encoding until it is really needed. This is /* We delay the encoding until it is really needed. This is
@ -319,7 +319,7 @@ passphrase_to_dek (int cipher_algo, STRING2KEY *s2k,
option processing in main(). */ option processing in main(). */
if (!opt.s2k_count) if (!opt.s2k_count)
opt.s2k_count = encode_s2k_iterations (agent_get_s2k_count ()); opt.s2k_count = encode_s2k_iterations (agent_get_s2k_count ());
s2k->count = opt.s2k_count; s2k->u.s.count = opt.s2k_count;
} }
} }
@ -330,7 +330,7 @@ passphrase_to_dek (int cipher_algo, STRING2KEY *s2k,
char buf[50]; char buf[50];
snprintf (buf, sizeof buf, "%d %d %d", snprintf (buf, sizeof buf, "%d %d %d",
cipher_algo, s2k->mode, s2k->hash_algo ); cipher_algo, s2k->mode, s2k->u.s.hash_algo );
write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf ); write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf );
} }
@ -352,7 +352,7 @@ passphrase_to_dek (int cipher_algo, STRING2KEY *s2k,
{ {
memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf); memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf);
*s2k_cacheidbuf = 'S'; *s2k_cacheidbuf = 'S';
bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1); bin2hex (s2k->u.s.salt, 8, s2k_cacheidbuf + 1);
s2k_cacheid = s2k_cacheidbuf; s2k_cacheid = s2k_cacheidbuf;
} }
@ -397,8 +397,8 @@ passphrase_to_dek (int cipher_algo, STRING2KEY *s2k,
s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K : s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
s2k->mode == 1? GCRY_KDF_SALTED_S2K : s2k->mode == 1? GCRY_KDF_SALTED_S2K :
/* */ GCRY_KDF_SIMPLE_S2K, /* */ GCRY_KDF_SIMPLE_S2K,
s2k->hash_algo, s2k->salt, 8, s2k->u.s.hash_algo, s2k->u.s.salt, 8,
S2K_DECODE_COUNT(s2k->count), S2K_DECODE_COUNT(s2k->u.s.count),
dek->keylen, dek->key); dek->keylen, dek->key);
if (err) if (err)
{ {

View File

@ -1609,7 +1609,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr)
/* Prepare key. */ /* Prepare key. */
s2k = xmalloc_clear (sizeof *s2k); s2k = xmalloc_clear (sizeof *s2k);
s2k->mode = opt.s2k_mode; s2k->mode = opt.s2k_mode;
s2k->hash_algo = S2K_DIGEST_ALGO; s2k->u.s.hash_algo = S2K_DIGEST_ALGO;
algo = default_cipher_algo (); algo = default_cipher_algo ();
cfx.dek = passphrase_to_dek (algo, s2k, 1, 1, NULL, 0, &canceled); cfx.dek = passphrase_to_dek (algo, s2k, 1, 1, NULL, 0, &canceled);