[botan-devel] False assertion 'The nonce is fresh for this message' (expression m_fresh_nonce)

Jack Lloyd lloyd at randombit.net
Wed Mar 9 14:20:53 EST 2016


Hi Lasse,

Thanks. This example is hitting a sanity check on the filter that a
new nonce is provided with each message. The code below is actually
(trying to) chain CBC IVs across the two messages, which is depending
on usage either insecure or 'just' a really bad idea.

To fix it the code would have to do something like

Keyed_Filter* mode = get_cipher("AES-128/CBC", ENCRYPTION)
Pipe pipe(mode); // Pipe takes ownership of this pointer
mode->set_iv(iv1);
pipe.process_msg(msg1);
mode->set_iv(iv2);
pipe.process_msg(msg2);

FWIW for new code using 1.11 only, I'd recommend staying away from the
filter interfaces entirely. They are an old design and have been part
of the library for a long time (and thus fairly well documented...)
but overly general in a away that imposes a lot of memory copies, and
a Pipe is difficult to reason about in code using it. You have a Pipe&
passed in by a caller - what does it do? Maybe it encrypts, maybe it
hashes, maybe both, maybe it does something else entirely ....  But
usually in your application you are trying to do just one specific
thing, and having this opaque data transform object usually confuses
more than it helps. I have been progressively removing uses of the
filter code from the library itself, and pulling the actual
functionality out leaving the available Filter types as just wrappers
around other APIs, with the intent of eventually making it at optional
in the build.

With the new in 1.11 interface, CBC encryption would look like
(untested code, see base/transform.h for the main API being called
here):

unique_ptr<Cipher_Mode> mode(get_cipher_mode("AES-128/CBC", ENCRYPTION));
secure_vector<uint8_t> buf;
buf.assign(my_plaintext);
mode->start(iv1);
mode->finish(buf);
// do something with buf

buf.assign(msg2);
mode->start(iv2);
mode->finish(buf);

Which probably doesn't seem hugely better in this snippet, but in real
application code this API seems to work out better. Cipher_Mode also
allows for incremental and inplace processing of messages without any
buffering or copies, which is just plain not possible with the Filter API.

With either interface, you would of course be better off specifying an
AEAD like "AES-128/GCM" or "ChaCha20Poly1305" rather than using
unauthenticted CBC as in the example. :/

Hope this helps,

Jack


On Wed, Mar 09, 2016 at 05:40:28PM +0000, Lasse Bromose wrote:
> Hi guys.
> 
> Im trying to run one of the examples in the user guide.
> http://botan.randombit.net/manual/filters.html
> 
> The first example with AES (there is a small error, after AutoSeeded_RNG rng should the ',' be changed to a ';').
> 
> How ever i am getting the following error:
> 
> terminate called after throwing an instance of 'Botan::Exception'
>   what():  False assertion 'The nonce is fresh for this message' (expression m_fresh_nonce) in get @src/lib/filters/transform_filter.cpp:49
> 
> I'm using version 1.11.28, gcc 5.3.0.
> 
> The code I've compiled looks as the following:
> 
> #include <iostream>
> 
> #include <botan/auto_rng.h>
> #include <botan/filters.h>
> #include <botan/block_cipher.h>
> #include <botan/version.h>
> 
> using namespace Botan;
> 
> int main(){
>   std::cout << version_string() << std::endl;
>   AutoSeeded_RNG rng;
>   SymmetricKey key(rng, 16); // a random 128-bit key
>   InitializationVector iv(rng, 16); // a random 128-bit IV
> 
>   // The algorithm we want is specified by a string
>   Pipe pipe(get_cipher("AES-128/CBC", key, iv, ENCRYPTION));
> 
>   pipe.process_msg("secrets");
>   pipe.process_msg("more secrets");
> 
>   secure_vector<byte> c1 = pipe.read_all(0);
> }
> 
> I really hope someone can help me :)
> 
> Best Regards
> Lasse

> _______________________________________________
> botan-devel mailing list
> botan-devel at randombit.net
> http://lists.randombit.net/mailman/listinfo/botan-devel



More information about the botan-devel mailing list