diff --git a/g10/build-packet.c b/g10/build-packet.c index 268bd71b2..2dbe7ee94 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -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 algorithm identifiers). */ 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_put (a, ski->s2k.mode - 1000); } else { 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) - iobuf_write (a, ski->s2k.salt, 8); + iobuf_write (a, ski->s2k.u.s.salt, 8); 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. */ 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) iobuf_put (a, enc->aead_algo); 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) { - iobuf_write (a, enc->s2k.salt, 8); + iobuf_write (a, enc->s2k.u.s.salt, 8); if (enc->s2k.mode == 3) - iobuf_put (a, enc->s2k.count); + iobuf_put (a, enc->s2k.u.s.count); } if (enc->seskeylen) iobuf_write (a, enc->seskey, enc->seskeylen); diff --git a/g10/encrypt.c b/g10/encrypt.c index d9af54ae6..767ac20e2 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -569,7 +569,7 @@ setup_symkey (STRING2KEY **symkey_s2k, DEK **symkey_dek) *symkey_s2k = xmalloc_clear (sizeof **symkey_s2k); (*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_s2k, 1, 0, NULL, 0, &canceled); diff --git a/g10/export.c b/g10/export.c index 1eec70935..d3e80de88 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1175,10 +1175,10 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) ski->sha1chk = 1; ski->algo = protect_algo; ski->s2k.mode = s2k_mode; - ski->s2k.hash_algo = s2k_algo; - log_assert (sizeof ski->s2k.salt == sizeof s2k_salt); - memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt); - ski->s2k.count = s2k_count; + ski->s2k.u.s.hash_algo = s2k_algo; + log_assert (sizeof ski->s2k.u.s.salt == sizeof s2k_salt); + memcpy (ski->s2k.u.s.salt, s2k_salt, sizeof s2k_salt); + ski->s2k.u.s.count = s2k_count; log_assert (ivlen <= sizeof ski->iv); memcpy (ski->iv, iv, ivlen); ski->ivlen = ivlen; diff --git a/g10/import.c b/g10/import.c index bb0bf6793..674f6437b 100644 --- a/g10/import.c +++ b/g10/import.c @@ -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 thus we send dummy data for the IV. */ snprintf (countbuf, sizeof countbuf, "%lu", - (unsigned long)ski->s2k.count); + (unsigned long)ski->s2k.u.s.count); err = gcry_sexp_build (&prot, NULL, " (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? ski->iv: (const unsigned char*)"X", ski->s2k.mode, - openpgp_md_algo_name (ski->s2k.hash_algo), - (int)sizeof (ski->s2k.salt), ski->s2k.salt, + openpgp_md_algo_name (ski->s2k.u.s.hash_algo), + (int)sizeof (ski->s2k.u.s.salt), ski->s2k.u.s.salt, countbuf); } else diff --git a/g10/mainproc.c b/g10/mainproc.c index aa028e91b..dfc582a17 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -388,10 +388,10 @@ proc_symkey_enc (CTX c, PACKET *pkt) 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" - " algorithm %d\n"),enc->s2k.hash_algo); + " algorithm %d\n"),enc->s2k.u.s.hash_algo); s = NULL; } @@ -662,7 +662,7 @@ proc_encrypted (CTX c, PACKET *pkt) { /* If no digest is given we assume SHA-1. */ s2kbuf.mode = 0; - s2kbuf.hash_algo = DIGEST_ALGO_SHA1; + s2kbuf.u.s.hash_algo = DIGEST_ALGO_SHA1; s2k = &s2kbuf; } log_info (_("assuming %s encrypted data\n"), "IDEA"); diff --git a/g10/packet.h b/g10/packet.h index b27beccdd..6cbe22ec7 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -86,14 +86,29 @@ typedef struct { byte value; } prefitem_t; -/* 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. */ +typedef struct { byte hash_algo; byte salt[8]; /* The *coded* (i.e., the serialized version) iteration 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; /* A symmetric-key encrypted session key packet as defined in RFC diff --git a/g10/parse-packet.c b/g10/parse-packet.c index bb05eabb7..38cf44f6f 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1275,15 +1275,15 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, k->cipher_algo = cipher_algo; k->aead_algo = aead_algo; k->s2k.mode = s2kmode; - k->s2k.hash_algo = hash_algo; + k->s2k.u.s.hash_algo = hash_algo; if (s2kmode == 1 || s2kmode == 3) { 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) { - k->s2k.count = iobuf_get_noeof (inp); + k->s2k.u.s.count = iobuf_get_noeof (inp); pktlen--; } k->seskeylen = seskeylen; @@ -1322,11 +1322,11 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, if (s2kmode == 1 || s2kmode == 3) { 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) es_fprintf (listfp, ", count %lu (%lu)", - S2K_DECODE_COUNT ((ulong) k->s2k.count), - (ulong) k->s2k.count); + S2K_DECODE_COUNT ((ulong) k->s2k.u.s.count), + (ulong) k->s2k.u.s.count); es_fprintf (listfp, "\n"); } } @@ -2676,7 +2676,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, if (ski->algo) { ski->is_protected = 1; - ski->s2k.count = 0; + ski->s2k.u.s.count = 0; if (ski->algo == 254 || ski->algo == 255) { if (pktlen < 3) @@ -2693,7 +2693,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, * to delete such a key. */ ski->s2k.mode = iobuf_get_noeof (inp); pktlen--; - ski->s2k.hash_algo = iobuf_get_noeof (inp); + ski->s2k.u.s.hash_algo = iobuf_get_noeof (inp); pktlen--; /* Check for the special GNU extension. */ 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); goto leave; } - memcpy (ski->s2k.salt, temp, 8); + memcpy (ski->s2k.u.s.salt, temp, 8); } /* Check the mode. */ @@ -2766,11 +2766,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, es_fprintf (listfp, ", algo: %d,%s hash: %d", ski->algo, 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) { 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); } @@ -2783,12 +2783,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, err = gpg_error (GPG_ERR_INV_PACKET); goto leave; } - ski->s2k.count = iobuf_get_noeof (inp); + ski->s2k.u.s.count = iobuf_get_noeof (inp); pktlen--; if (list_mode) es_fprintf (listfp, "\tprotect count: %lu (%lu)\n", - (ulong)S2K_DECODE_COUNT ((ulong)ski->s2k.count), - (ulong) ski->s2k.count); + (ulong)S2K_DECODE_COUNT ((ulong)ski->s2k.u.s.count), + (ulong) ski->s2k.u.s.count); } 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 way to delete such a key. */ ski->s2k.mode = 0; - ski->s2k.hash_algo = DIGEST_ALGO_MD5; + ski->s2k.u.s.hash_algo = DIGEST_ALGO_MD5; if (list_mode) 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 diff --git a/g10/passphrase.c b/g10/passphrase.c index 604452d46..cb951424d 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -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 */ memset (&help_s2k, 0, sizeof (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 new key. */ 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 ) { /* 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(). */ if (!opt.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]; 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 ); } @@ -352,7 +352,7 @@ passphrase_to_dek (int cipher_algo, STRING2KEY *s2k, { memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf); *s2k_cacheidbuf = 'S'; - bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1); + bin2hex (s2k->u.s.salt, 8, s2k_cacheidbuf + 1); 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 == 1? GCRY_KDF_SALTED_S2K : /* */ GCRY_KDF_SIMPLE_S2K, - s2k->hash_algo, s2k->salt, 8, - S2K_DECODE_COUNT(s2k->count), + s2k->u.s.hash_algo, s2k->u.s.salt, 8, + S2K_DECODE_COUNT(s2k->u.s.count), dek->keylen, dek->key); if (err) { diff --git a/g10/sign.c b/g10/sign.c index 98cfcb2e3..150afd4f2 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1609,7 +1609,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) /* Prepare key. */ s2k = xmalloc_clear (sizeof *s2k); s2k->mode = opt.s2k_mode; - s2k->hash_algo = S2K_DIGEST_ALGO; + s2k->u.s.hash_algo = S2K_DIGEST_ALGO; algo = default_cipher_algo (); cfx.dek = passphrase_to_dek (algo, s2k, 1, 1, NULL, 0, &canceled);