mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: New option --chunk-size.
* g10/gpg.c (opts): New option --chunk-size. (oChunkSize): New const. (build_list_aead_test_algo, build_list_aead_algo_name): New. (my_strusage): List AEAD algos. (main): Implement --chunk-size.. * g10/options.h (struct opt): Add field 'chunk_size'. (DBG_IPC): Remove duplicated macro. * g10/main.h (DEFAULT_AEAD_ALGO): Depend on Libgcrypt version. * g10/misc.c (openpgp_aead_test_algo): Ditto. * g10/cipher-aead.c: Silence if not in debug mode. * g10/decrypt-data.c: Ditto. -- And that new option immediatley revealed bugs in our chunking code :-(.
This commit is contained in:
parent
112e02ee89
commit
f3ef8b0dca
56
doc/gpg.texi
56
doc/gpg.texi
@ -2255,6 +2255,16 @@ works properly with such messages, there is often a desire to set a
|
|||||||
maximum file size that will be generated before processing is forced to
|
maximum file size that will be generated before processing is forced to
|
||||||
stop by the OS limits. Defaults to 0, which means "no limit".
|
stop by the OS limits. Defaults to 0, which means "no limit".
|
||||||
|
|
||||||
|
@item --chunk-size @var{n}
|
||||||
|
@opindex chunk-size
|
||||||
|
The AEAD encryption mode encrypts the data in chunks so that a
|
||||||
|
receiving side can check for transmission errors or tampering at the
|
||||||
|
end of each chunk and does not need to delay this until all data has
|
||||||
|
been received. The used chunk size is 2^@var{n} byte. The lowest
|
||||||
|
allowed value for @var{n} is 6 (64 byte) and the largest is 62 (4
|
||||||
|
EiB). The default value for @var{n} is 30 which creates chunks not
|
||||||
|
larger than 1 GiB.
|
||||||
|
|
||||||
@item --input-size-hint @var{n}
|
@item --input-size-hint @var{n}
|
||||||
@opindex input-size-hint
|
@opindex input-size-hint
|
||||||
This option can be used to tell GPG the size of the input data in
|
This option can be used to tell GPG the size of the input data in
|
||||||
@ -2592,6 +2602,16 @@ is the default.
|
|||||||
@itemx --no-force-v4-certs
|
@itemx --no-force-v4-certs
|
||||||
These options are obsolete and have no effect since GnuPG 2.1.
|
These options are obsolete and have no effect since GnuPG 2.1.
|
||||||
|
|
||||||
|
@item --force-aead
|
||||||
|
@opindex force-aead
|
||||||
|
Force the use of AEAD encryption over MDC encryption. AEAD is a
|
||||||
|
modern and faster way to do authenticated encrytion than the old MDC
|
||||||
|
method. See also options @option{--aead-algo} and
|
||||||
|
@option{--chunk-size}.
|
||||||
|
|
||||||
|
This option requires the use of option @option{--rfc4880bis} to
|
||||||
|
declare that a not yet standardized feature is used.
|
||||||
|
|
||||||
@item --force-mdc
|
@item --force-mdc
|
||||||
@opindex force-mdc
|
@opindex force-mdc
|
||||||
Force the use of encryption with a modification detection code. This
|
Force the use of encryption with a modification detection code. This
|
||||||
@ -2623,6 +2643,16 @@ preferences, as GPG will only select an algorithm that is usable by
|
|||||||
all recipients. The most highly ranked cipher in this list is also
|
all recipients. The most highly ranked cipher in this list is also
|
||||||
used for the @option{--symmetric} encryption command.
|
used for the @option{--symmetric} encryption command.
|
||||||
|
|
||||||
|
@item --personal-aead-preferences @var{string}
|
||||||
|
@opindex personal-aead-preferences
|
||||||
|
Set the list of personal AEAD preferences to @var{string}. Use
|
||||||
|
@command{@gpgname --version} to get a list of available algorithms,
|
||||||
|
and use @code{none} to set no preference at all. This allows the user
|
||||||
|
to safely override the algorithm chosen by the recipient key
|
||||||
|
preferences, as GPG will only select an algorithm that is usable by
|
||||||
|
all recipients. The most highly ranked cipher in this list is also
|
||||||
|
used for the @option{--symmetric} encryption command.
|
||||||
|
|
||||||
@item --personal-digest-preferences @var{string}
|
@item --personal-digest-preferences @var{string}
|
||||||
@opindex personal-digest-preferences
|
@opindex personal-digest-preferences
|
||||||
Set the list of personal digest preferences to @var{string}. Use
|
Set the list of personal digest preferences to @var{string}. Use
|
||||||
@ -2981,17 +3011,28 @@ Use @var{name} as cipher algorithm. Running the program with the
|
|||||||
command @option{--version} yields a list of supported algorithms. If
|
command @option{--version} yields a list of supported algorithms. If
|
||||||
this is not used the cipher algorithm is selected from the preferences
|
this is not used the cipher algorithm is selected from the preferences
|
||||||
stored with the key. In general, you do not want to use this option as
|
stored with the key. In general, you do not want to use this option as
|
||||||
it allows you to violate the OpenPGP standard.
|
it allows you to violate the OpenPGP standard. The option
|
||||||
@option{--personal-cipher-preferences} is the safe way to accomplish the
|
@option{--personal-cipher-preferences} is the safe way to accomplish the
|
||||||
same thing.
|
same thing.
|
||||||
|
|
||||||
|
@item --aead-algo @var{name}
|
||||||
|
@opindex aead-algo
|
||||||
|
Specify that the AEAD algorithm @var{name} is to be used. This is
|
||||||
|
useful for symmetric encryption where no key preference are available
|
||||||
|
to select the AEAD algorithm. Runing @command{@gpgname} with option
|
||||||
|
@option{--version} shows the available AEAD algorithms. In general,
|
||||||
|
you do not want to use this option as it allows you to violate the
|
||||||
|
OpenPGP standard. The option @option{--personal-aead-preferences} is
|
||||||
|
the safe way to accomplish the same thing.
|
||||||
|
|
||||||
@item --digest-algo @var{name}
|
@item --digest-algo @var{name}
|
||||||
@opindex digest-algo
|
@opindex digest-algo
|
||||||
Use @var{name} as the message digest algorithm. Running the program
|
Use @var{name} as the message digest algorithm. Running the program
|
||||||
with the command @option{--version} yields a list of supported algorithms. In
|
with the command @option{--version} yields a list of supported
|
||||||
general, you do not want to use this option as it allows you to
|
algorithms. In general, you do not want to use this option as it
|
||||||
violate the OpenPGP standard. @option{--personal-digest-preferences} is the
|
allows you to violate the OpenPGP standard. The option
|
||||||
safe way to accomplish the same thing.
|
@option{--personal-digest-preferences} is the safe way to accomplish
|
||||||
|
the same thing.
|
||||||
|
|
||||||
@item --compress-algo @var{name}
|
@item --compress-algo @var{name}
|
||||||
@opindex compress-algo
|
@opindex compress-algo
|
||||||
@ -3013,8 +3054,9 @@ significant in low memory situations. Note, however, that PGP (all
|
|||||||
versions) only supports ZIP compression. Using any algorithm other
|
versions) only supports ZIP compression. Using any algorithm other
|
||||||
than ZIP or "none" will make the message unreadable with PGP. In
|
than ZIP or "none" will make the message unreadable with PGP. In
|
||||||
general, you do not want to use this option as it allows you to
|
general, you do not want to use this option as it allows you to
|
||||||
violate the OpenPGP standard. @option{--personal-compress-preferences} is the
|
violate the OpenPGP standard. The option
|
||||||
safe way to accomplish the same thing.
|
@option{--personal-compress-preferences} is the safe way to accomplish
|
||||||
|
the same thing.
|
||||||
|
|
||||||
@item --cert-digest-algo @var{name}
|
@item --cert-digest-algo @var{name}
|
||||||
@opindex cert-digest-algo
|
@opindex cert-digest-algo
|
||||||
|
@ -86,7 +86,8 @@ set_additional_data (cipher_filter_context_t *cfx, int final)
|
|||||||
ad[19] = cfx->total >> 8;
|
ad[19] = cfx->total >> 8;
|
||||||
ad[20] = cfx->total;
|
ad[20] = cfx->total;
|
||||||
}
|
}
|
||||||
log_printhex (ad, final? 21 : 13, "authdata:");
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (ad, final? 21 : 13, "authdata:");
|
||||||
return gcry_cipher_authenticate (cfx->cipher_hd, ad, final? 21 : 13);
|
return gcry_cipher_authenticate (cfx->cipher_hd, ad, final? 21 : 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +125,8 @@ set_nonce (cipher_filter_context_t *cfx)
|
|||||||
nonce[i++] ^= cfx->chunkindex >> 8;
|
nonce[i++] ^= cfx->chunkindex >> 8;
|
||||||
nonce[i++] ^= cfx->chunkindex;
|
nonce[i++] ^= cfx->chunkindex;
|
||||||
|
|
||||||
log_printhex (nonce, 15, "nonce:");
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (nonce, 15, "nonce:");
|
||||||
return gcry_cipher_setiv (cfx->cipher_hd, nonce, i);
|
return gcry_cipher_setiv (cfx->cipher_hd, nonce, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +151,8 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a)
|
|||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
cfx->chunkbyte = 10;
|
log_assert (opt.chunk_size >= 6 && opt.chunk_size <= 62);
|
||||||
|
cfx->chunkbyte = opt.chunk_size - 6;
|
||||||
cfx->chunksize = (uint64_t)1 << (cfx->chunkbyte + 6);
|
cfx->chunksize = (uint64_t)1 << (cfx->chunkbyte + 6);
|
||||||
cfx->chunklen = 0;
|
cfx->chunklen = 0;
|
||||||
cfx->bufsize = AEAD_ENC_BUFFER_SIZE;
|
cfx->bufsize = AEAD_ENC_BUFFER_SIZE;
|
||||||
@ -170,8 +173,9 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a)
|
|||||||
pkt.pkttype = PKT_ENCRYPTED_AEAD;
|
pkt.pkttype = PKT_ENCRYPTED_AEAD;
|
||||||
pkt.pkt.encrypted = &ed;
|
pkt.pkt.encrypted = &ed;
|
||||||
|
|
||||||
log_debug ("aead packet: len=%lu extralen=%d\n",
|
if (DBG_FILTER)
|
||||||
(unsigned long)ed.len, ed.extralen);
|
log_debug ("aead packet: len=%lu extralen=%d\n",
|
||||||
|
(unsigned long)ed.len, ed.extralen);
|
||||||
|
|
||||||
write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d",
|
write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d",
|
||||||
cfx->dek->algo, ed.aead_algo);
|
cfx->dek->algo, ed.aead_algo);
|
||||||
@ -193,7 +197,8 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a)
|
|||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
log_printhex (cfx->dek->key, cfx->dek->keylen, "thekey:");
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (cfx->dek->key, cfx->dek->keylen, "thekey:");
|
||||||
err = gcry_cipher_setkey (cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen);
|
err = gcry_cipher_setkey (cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -226,7 +231,6 @@ write_auth_tag (cipher_filter_context_t *cfx, iobuf_t a)
|
|||||||
err = my_iobuf_write (a, tag, 16);
|
err = my_iobuf_write (a, tag, 16);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
log_printhex (tag, 16, "wrote tag:");
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
return err;
|
return err;
|
||||||
@ -272,7 +276,8 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
|
|||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
/* Put the data into a buffer, flush and encrypt as needed. */
|
/* Put the data into a buffer, flush and encrypt as needed. */
|
||||||
log_debug ("flushing %zu bytes (cur buflen=%zu)\n", size, cfx->buflen);
|
if (DBG_FILTER)
|
||||||
|
log_debug ("flushing %zu bytes (cur buflen=%zu)\n", size, cfx->buflen);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (cfx->buflen + size < cfx->bufsize)
|
if (cfx->buflen + size < cfx->bufsize)
|
||||||
@ -284,10 +289,11 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
|
|||||||
{
|
{
|
||||||
size_t n1 = cfx->chunksize - cfx->chunklen;
|
size_t n1 = cfx->chunksize - cfx->chunklen;
|
||||||
newchunk = 1;
|
newchunk = 1;
|
||||||
log_debug ("chunksize %ju reached;"
|
if (DBG_FILTER)
|
||||||
" cur buflen=%zu using %zu of %zu\n",
|
log_debug ("chunksize %ju reached;"
|
||||||
(uintmax_t)cfx->chunksize, (uintmax_t)cfx->buflen,
|
" cur buflen=%zu using %zu of %zu\n",
|
||||||
n1, n);
|
(uintmax_t)cfx->chunksize, (uintmax_t)cfx->buflen,
|
||||||
|
n1, n);
|
||||||
n = n1;
|
n = n1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,11 +304,14 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
|
|||||||
|
|
||||||
if (cfx->buflen == cfx->bufsize || newchunk)
|
if (cfx->buflen == cfx->bufsize || newchunk)
|
||||||
{
|
{
|
||||||
log_debug ("encrypting: buflen=%zu %s %p\n",
|
if (DBG_FILTER)
|
||||||
cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd);
|
log_debug ("encrypting: buflen=%zu %s %p\n",
|
||||||
|
cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd);
|
||||||
if (newchunk)
|
if (newchunk)
|
||||||
gcry_cipher_final (cfx->cipher_hd);
|
gcry_cipher_final (cfx->cipher_hd);
|
||||||
if (newchunk)
|
if (!DBG_FILTER)
|
||||||
|
;
|
||||||
|
else if (newchunk)
|
||||||
log_printhex (cfx->buffer, cfx->buflen, "plain(1):");
|
log_printhex (cfx->buffer, cfx->buflen, "plain(1):");
|
||||||
else if (cfx->buflen > 32)
|
else if (cfx->buflen > 32)
|
||||||
log_printhex (cfx->buffer + cfx->buflen - 32, 32,
|
log_printhex (cfx->buffer + cfx->buflen - 32, 32,
|
||||||
@ -314,7 +323,7 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
|
|||||||
* mode. */
|
* mode. */
|
||||||
gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen,
|
gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
if (newchunk)
|
if (newchunk && DBG_FILTER)
|
||||||
log_printhex (cfx->buffer, cfx->buflen, "ciphr(1):");
|
log_printhex (cfx->buffer, cfx->buflen, "ciphr(1):");
|
||||||
err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
|
err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
|
||||||
if (err)
|
if (err)
|
||||||
@ -325,18 +334,19 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
|
|||||||
|
|
||||||
if (newchunk)
|
if (newchunk)
|
||||||
{
|
{
|
||||||
log_debug ("chunklen=%ju total=%ju\n",
|
if (DBG_FILTER)
|
||||||
(uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
|
log_debug ("chunklen=%ju total=%ju\n",
|
||||||
|
(uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
|
||||||
err = write_auth_tag (cfx, a);
|
err = write_auth_tag (cfx, a);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("gcry_cipher_gettag failed: %s\n",
|
log_error ("gcry_cipher_gettag failed: %s\n",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug ("starting a new chunk (cur size=%zu)\n", size);
|
if (DBG_FILTER)
|
||||||
log_printhex (buf, size, "cur buf:");
|
log_debug ("starting a new chunk (cur size=%zu)\n", size);
|
||||||
cfx->chunkindex++;
|
cfx->chunkindex++;
|
||||||
cfx->chunklen = 0;
|
cfx->chunklen = 0;
|
||||||
err = set_nonce (cfx);
|
err = set_nonce (cfx);
|
||||||
@ -373,10 +383,10 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a)
|
|||||||
/* Encrypt any remaining bytes. */
|
/* Encrypt any remaining bytes. */
|
||||||
if (cfx->buflen)
|
if (cfx->buflen)
|
||||||
{
|
{
|
||||||
log_debug ("processing last %zu bytes of the last chunk\n", cfx->buflen);
|
if (DBG_FILTER)
|
||||||
log_printhex (cfx->buffer, cfx->buflen, "plain(2):");
|
log_debug ("processing last %zu bytes of the last chunk\n",
|
||||||
|
cfx->buflen);
|
||||||
gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, NULL, 0);
|
gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, NULL, 0);
|
||||||
log_printhex (cfx->buffer, cfx->buflen, "ciphr(2):");
|
|
||||||
err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
|
err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -386,14 +396,16 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get and write the authentication tag. */
|
/* Get and write the authentication tag. */
|
||||||
log_debug ("chunklen=%ju total=%ju\n",
|
if (DBG_FILTER)
|
||||||
(uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
|
log_debug ("chunklen=%ju total=%ju\n",
|
||||||
|
(uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
|
||||||
err = write_auth_tag (cfx, a);
|
err = write_auth_tag (cfx, a);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
/* Write the final chunk. */
|
/* Write the final chunk. */
|
||||||
log_debug ("creating final chunk\n");
|
if (DBG_FILTER)
|
||||||
|
log_debug ("creating final chunk\n");
|
||||||
err = write_final_chunk (cfx, a);
|
err = write_final_chunk (cfx, a);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
@ -150,7 +150,8 @@ aead_set_nonce (decode_filter_ctx_t dfx)
|
|||||||
nonce[i++] ^= dfx->chunkindex >> 8;
|
nonce[i++] ^= dfx->chunkindex >> 8;
|
||||||
nonce[i++] ^= dfx->chunkindex;
|
nonce[i++] ^= dfx->chunkindex;
|
||||||
|
|
||||||
log_printhex (nonce, i, "nonce:");
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (nonce, i, "nonce:");
|
||||||
return gcry_cipher_setiv (dfx->cipher_hd, nonce, i);
|
return gcry_cipher_setiv (dfx->cipher_hd, nonce, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +187,8 @@ aead_set_ad (decode_filter_ctx_t dfx, int final)
|
|||||||
ad[19] = dfx->total >> 8;
|
ad[19] = dfx->total >> 8;
|
||||||
ad[20] = dfx->total;
|
ad[20] = dfx->total;
|
||||||
}
|
}
|
||||||
log_printhex (ad, final? 21 : 13, "authdata:");
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (ad, final? 21 : 13, "authdata:");
|
||||||
return gcry_cipher_authenticate (dfx->cipher_hd, ad, final? 21 : 13);
|
return gcry_cipher_authenticate (dfx->cipher_hd, ad, final? 21 : 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +329,8 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto leave; /* Should never happen. */
|
goto leave; /* Should never happen. */
|
||||||
|
|
||||||
log_printhex (dek->key, dek->keylen, "thekey:");
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (dek->key, dek->keylen, "thekey:");
|
||||||
rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
|
rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
|
||||||
if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
|
if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
|
||||||
{
|
{
|
||||||
@ -631,9 +634,10 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
|
|||||||
dfx->eof_seen = 1; /* Normal EOF. */
|
dfx->eof_seen = 1; /* Normal EOF. */
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug ("decrypt: chunklen=%ju total=%ju size=%zu n=%zu%s\n",
|
if (DBG_FILTER)
|
||||||
(uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, size, n,
|
log_debug ("decrypt: chunklen=%ju total=%ju size=%zu n=%zu%s\n",
|
||||||
dfx->eof_seen? " eof":"");
|
(uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, size, n,
|
||||||
|
dfx->eof_seen? " eof":"");
|
||||||
|
|
||||||
/* Now decrypt the buffer. */
|
/* Now decrypt the buffer. */
|
||||||
if (n && dfx->eof_seen > 1)
|
if (n && dfx->eof_seen > 1)
|
||||||
@ -653,12 +657,13 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
|
|||||||
{
|
{
|
||||||
size_t n0 = dfx->chunksize - dfx->chunklen;
|
size_t n0 = dfx->chunksize - dfx->chunklen;
|
||||||
|
|
||||||
log_debug ("chunksize will be reached: n0=%zu\n", n0);
|
if (DBG_FILTER)
|
||||||
|
log_debug ("chunksize will be reached: n0=%zu\n", n0);
|
||||||
gcry_cipher_final (dfx->cipher_hd);
|
gcry_cipher_final (dfx->cipher_hd);
|
||||||
err = gcry_cipher_decrypt (dfx->cipher_hd, buf, n0, NULL, 0);
|
err = gcry_cipher_decrypt (dfx->cipher_hd, buf, n0, NULL, 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("gcry_cipher_decrypt failed (1): %s\n",
|
log_error ("gcry_cipher_decrypt failed (1): %s\n",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -668,15 +673,18 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
|
|||||||
off = n0;
|
off = n0;
|
||||||
n -= n0;
|
n -= n0;
|
||||||
|
|
||||||
log_debug ("bytes left: %zu off=%zu\n", n, off);
|
if (DBG_FILTER)
|
||||||
|
log_debug ("bytes left: %zu off=%zu\n", n, off);
|
||||||
log_assert (n >= 16);
|
log_assert (n >= 16);
|
||||||
log_assert (dfx->defer_filled);
|
log_assert (dfx->defer_filled);
|
||||||
log_printhex (buf+off, 16, "tag:");
|
if (DBG_CRYPTO)
|
||||||
|
log_printhex (buf+off, 16, "tag:");
|
||||||
err = gcry_cipher_checktag (dfx->cipher_hd, buf + off, 16);
|
err = gcry_cipher_checktag (dfx->cipher_hd, buf + off, 16);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("gcry_cipher_checktag failed (1): %s\n",
|
if (DBG_FILTER)
|
||||||
gpg_strerror (err));
|
log_debug ("gcry_cipher_checktag failed (1): %s\n",
|
||||||
|
gpg_strerror (err));
|
||||||
/* Return Bad Signature like we do with MDC encryption. */
|
/* Return Bad Signature like we do with MDC encryption. */
|
||||||
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
|
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
|
||||||
err = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
err = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
||||||
@ -714,7 +722,8 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
|
|||||||
err = gcry_cipher_decrypt (dfx->cipher_hd, buf + off, n, NULL, 0);
|
err = gcry_cipher_decrypt (dfx->cipher_hd, buf + off, n, NULL, 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("gcry_cipher_decrypt failed (2): %s\n",gpg_strerror (err));
|
log_error ("gcry_cipher_decrypt failed (2): %s\n",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
dfx->chunklen += n;
|
dfx->chunklen += n;
|
||||||
@ -723,14 +732,15 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
|
|||||||
if (dfx->eof_seen)
|
if (dfx->eof_seen)
|
||||||
{
|
{
|
||||||
/* log_printhex (buf+off, n, "buf+off:"); */
|
/* log_printhex (buf+off, n, "buf+off:"); */
|
||||||
log_debug ("eof seen: chunklen=%ju total=%ju off=%zu n=%zu\n",
|
if (DBG_FILTER)
|
||||||
(uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, off, n);
|
log_debug ("eof seen: chunklen=%ju total=%ju off=%zu n=%zu\n",
|
||||||
|
(uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, off, n);
|
||||||
|
|
||||||
log_assert (dfx->defer_filled);
|
log_assert (dfx->defer_filled);
|
||||||
err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer, 16);
|
err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer, 16);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("gcry_cipher_checktag failed (2): %s\n",
|
log_error ("gcry_cipher_checktag failed (2): %s\n",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
/* Return Bad Signature like we do with MDC encryption. */
|
/* Return Bad Signature like we do with MDC encryption. */
|
||||||
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
|
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
|
||||||
@ -751,15 +761,16 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
|
|||||||
err = gcry_cipher_decrypt (dfx->cipher_hd, buf, 0, NULL, 0);
|
err = gcry_cipher_decrypt (dfx->cipher_hd, buf, 0, NULL, 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("gcry_cipher_decrypt failed (final): %s\n",
|
log_error ("gcry_cipher_decrypt failed (final): %s\n",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer+16, 16);
|
err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer+16, 16);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("gcry_cipher_checktag failed (final): %s\n",
|
if (DBG_FILTER)
|
||||||
gpg_strerror (err));
|
log_debug ("gcry_cipher_checktag failed (final): %s\n",
|
||||||
|
gpg_strerror (err));
|
||||||
/* Return Bad Signature like we do with MDC encryption. */
|
/* Return Bad Signature like we do with MDC encryption. */
|
||||||
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
|
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
|
||||||
err = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
err = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
||||||
@ -767,7 +778,8 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n += off;
|
n += off;
|
||||||
log_debug ("eof seen: returning %zu\n", n);
|
if (DBG_FILTER)
|
||||||
|
log_debug ("eof seen: returning %zu\n", n);
|
||||||
/* log_printhex (buf, n, "buf:"); */
|
/* log_printhex (buf, n, "buf:"); */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
48
g10/gpg.c
48
g10/gpg.c
@ -105,6 +105,7 @@ enum cmd_and_opt_values
|
|||||||
oBatch = 500,
|
oBatch = 500,
|
||||||
oMaxOutput,
|
oMaxOutput,
|
||||||
oInputSizeHint,
|
oInputSizeHint,
|
||||||
|
oChunkSize,
|
||||||
oSigNotation,
|
oSigNotation,
|
||||||
oCertNotation,
|
oCertNotation,
|
||||||
oShowNotation,
|
oShowNotation,
|
||||||
@ -596,6 +597,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
|
ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
|
||||||
ARGPARSE_p_u (oMaxOutput, "max-output", "@"),
|
ARGPARSE_p_u (oMaxOutput, "max-output", "@"),
|
||||||
ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"),
|
ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"),
|
||||||
|
ARGPARSE_s_i (oChunkSize, "chunk-size", "@"),
|
||||||
|
|
||||||
ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
|
ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
|
||||||
ARGPARSE_s_n (oQuiet, "quiet", "@"),
|
ARGPARSE_s_n (oQuiet, "quiet", "@"),
|
||||||
@ -1015,6 +1017,18 @@ build_list_cipher_algo_name (int algo)
|
|||||||
return openpgp_cipher_algo_name (algo);
|
return openpgp_cipher_algo_name (algo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
build_list_aead_test_algo (int algo)
|
||||||
|
{
|
||||||
|
return openpgp_aead_test_algo (algo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
build_list_aead_algo_name (int algo)
|
||||||
|
{
|
||||||
|
return openpgp_aead_algo_name (algo);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
build_list_md_test_algo (int algo)
|
build_list_md_test_algo (int algo)
|
||||||
{
|
{
|
||||||
@ -1036,7 +1050,7 @@ build_list_md_algo_name (int algo)
|
|||||||
static const char *
|
static const char *
|
||||||
my_strusage( int level )
|
my_strusage( int level )
|
||||||
{
|
{
|
||||||
static char *digests, *pubkeys, *ciphers, *zips, *ver_gcry;
|
static char *digests, *pubkeys, *ciphers, *zips, *aeads, *ver_gcry;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
switch( level ) {
|
switch( level ) {
|
||||||
@ -1096,13 +1110,20 @@ my_strusage( int level )
|
|||||||
p = ciphers;
|
p = ciphers;
|
||||||
break;
|
break;
|
||||||
case 36:
|
case 36:
|
||||||
|
if (!aeads)
|
||||||
|
aeads = build_list ("AEAD: ", 'A',
|
||||||
|
build_list_aead_algo_name,
|
||||||
|
build_list_aead_test_algo);
|
||||||
|
p = aeads;
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
if( !digests )
|
if( !digests )
|
||||||
digests = build_list(_("Hash: "), 'H',
|
digests = build_list(_("Hash: "), 'H',
|
||||||
build_list_md_algo_name,
|
build_list_md_algo_name,
|
||||||
build_list_md_test_algo );
|
build_list_md_test_algo );
|
||||||
p = digests;
|
p = digests;
|
||||||
break;
|
break;
|
||||||
case 37:
|
case 38:
|
||||||
if( !zips )
|
if( !zips )
|
||||||
zips = build_list(_("Compression: "),'Z',
|
zips = build_list(_("Compression: "),'Z',
|
||||||
compress_algo_to_string,
|
compress_algo_to_string,
|
||||||
@ -1123,6 +1144,7 @@ build_list (const char *text, char letter,
|
|||||||
membuf_t mb;
|
membuf_t mb;
|
||||||
int indent;
|
int indent;
|
||||||
int i, j, len;
|
int i, j, len;
|
||||||
|
int limit;
|
||||||
const char *s;
|
const char *s;
|
||||||
char *string;
|
char *string;
|
||||||
|
|
||||||
@ -1133,7 +1155,8 @@ build_list (const char *text, char letter,
|
|||||||
len = 0;
|
len = 0;
|
||||||
init_membuf (&mb, 512);
|
init_membuf (&mb, 512);
|
||||||
|
|
||||||
for (i=0; i <= 110; i++ )
|
limit = (letter == 'A')? 4 : 110;
|
||||||
|
for (i=0; i <= limit; i++ )
|
||||||
{
|
{
|
||||||
if (!chkf (i) && (s = mapf (i)))
|
if (!chkf (i) && (s = mapf (i)))
|
||||||
{
|
{
|
||||||
@ -2648,6 +2671,10 @@ main (int argc, char **argv)
|
|||||||
opt.input_size_hint = string_to_u64 (pargs.r.ret_str);
|
opt.input_size_hint = string_to_u64 (pargs.r.ret_str);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case oChunkSize:
|
||||||
|
opt.chunk_size = pargs.r.ret_int;
|
||||||
|
break;
|
||||||
|
|
||||||
case oQuiet: opt.quiet = 1; break;
|
case oQuiet: opt.quiet = 1; break;
|
||||||
case oNoTTY: tty_no_terminal(1); break;
|
case oNoTTY: tty_no_terminal(1); break;
|
||||||
case oDryRun: opt.dry_run = 1; break;
|
case oDryRun: opt.dry_run = 1; break;
|
||||||
@ -3836,6 +3863,21 @@ main (int argc, char **argv)
|
|||||||
keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
|
keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
|
||||||
log_error(_("invalid personal compress preferences\n"));
|
log_error(_("invalid personal compress preferences\n"));
|
||||||
|
|
||||||
|
/* Check chunk size. Please fix also the man page if you chnage
|
||||||
|
* the default. The limits are given by the specs. */
|
||||||
|
if (!opt.chunk_size)
|
||||||
|
opt.chunk_size = 30; /* Default to 1 GiB chunks. */
|
||||||
|
else if (opt.chunk_size < 6)
|
||||||
|
{
|
||||||
|
opt.chunk_size = 6;
|
||||||
|
log_info (_("chunk size invalid - using %d\n"), opt.chunk_size);
|
||||||
|
}
|
||||||
|
else if (opt.chunk_size > 62)
|
||||||
|
{
|
||||||
|
opt.chunk_size = 62;
|
||||||
|
log_info (_("chunk size invalid - using %d\n"), opt.chunk_size);
|
||||||
|
}
|
||||||
|
|
||||||
/* We don't support all possible commands with multifile yet */
|
/* We don't support all possible commands with multifile yet */
|
||||||
if(multifile)
|
if(multifile)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,11 @@
|
|||||||
# define DEFAULT_CIPHER_ALGO CIPHER_ALGO_3DES
|
# define DEFAULT_CIPHER_ALGO CIPHER_ALGO_3DES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_AEAD_ALGO AEAD_ALGO_EAX
|
#if GCRYPT_VERSION_NUMBER < 0x019000
|
||||||
|
# define DEFAULT_AEAD_ALGO AEAD_ALGO_OCB
|
||||||
|
#else
|
||||||
|
# define DEFAULT_AEAD_ALGO AEAD_ALGO_EAX
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_DIGEST_ALGO ((GNUPG)? DIGEST_ALGO_SHA256:DIGEST_ALGO_SHA1)
|
#define DEFAULT_DIGEST_ALGO ((GNUPG)? DIGEST_ALGO_SHA256:DIGEST_ALGO_SHA1)
|
||||||
#define DEFAULT_S2K_DIGEST_ALGO DIGEST_ALGO_SHA1
|
#define DEFAULT_S2K_DIGEST_ALGO DIGEST_ALGO_SHA1
|
||||||
|
12
g10/misc.c
12
g10/misc.c
@ -591,11 +591,23 @@ openpgp_cipher_algo_name (cipher_algo_t algo)
|
|||||||
gpg_error_t
|
gpg_error_t
|
||||||
openpgp_aead_test_algo (aead_algo_t algo)
|
openpgp_aead_test_algo (aead_algo_t algo)
|
||||||
{
|
{
|
||||||
|
/* FIXME: We currently have no easy way to test whether libgcrypt
|
||||||
|
* implements a mode. The only way we can do this is to open a
|
||||||
|
* cipher context with that mode and close it immediately. That is
|
||||||
|
* a bit costly. So we look at the libgcrypt version and assume
|
||||||
|
* nothing has been patched out. */
|
||||||
switch (algo)
|
switch (algo)
|
||||||
{
|
{
|
||||||
case AEAD_ALGO_NONE:
|
case AEAD_ALGO_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AEAD_ALGO_EAX:
|
case AEAD_ALGO_EAX:
|
||||||
|
#if GCRYPT_VERSION_NUMBER < 0x010900
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
case AEAD_ALGO_OCB:
|
case AEAD_ALGO_OCB:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,9 @@ struct
|
|||||||
* progress info and to decide on how to allocate buffers. */
|
* progress info and to decide on how to allocate buffers. */
|
||||||
uint64_t input_size_hint;
|
uint64_t input_size_hint;
|
||||||
|
|
||||||
|
/* The AEAD chunk size expressed as a power of 2. */
|
||||||
|
int chunk_size;
|
||||||
|
|
||||||
int dry_run;
|
int dry_run;
|
||||||
int autostart;
|
int autostart;
|
||||||
int list_only;
|
int list_only;
|
||||||
@ -319,7 +322,6 @@ struct {
|
|||||||
#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE)
|
#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE)
|
||||||
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
||||||
#define DBG_IPC (opt.debug & DBG_IPC_VALUE)
|
#define DBG_IPC (opt.debug & DBG_IPC_VALUE)
|
||||||
#define DBG_IPC (opt.debug & DBG_IPC_VALUE)
|
|
||||||
#define DBG_CLOCK (opt.debug & DBG_CLOCK_VALUE)
|
#define DBG_CLOCK (opt.debug & DBG_CLOCK_VALUE)
|
||||||
#define DBG_LOOKUP (opt.debug & DBG_LOOKUP_VALUE)
|
#define DBG_LOOKUP (opt.debug & DBG_LOOKUP_VALUE)
|
||||||
#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE)
|
#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user