Nikos Mavrogiannopoulos <[email protected]> writes:

> The disadvantage here is that I need to define encrypt and decrypt
> functions for each possible cipher and mode. That was the reason for
> the usage of cbc_encrypt() and decrypt.

Maybe it's possible with some trickery.

For cbc modes, you could allocate a context which is a pointer to the
nettle_cipher struct followed by a CBC_CTX with cipher context and iv.
Then you could do

nettle_crypt_func gnutls_cbc_encrypt;

struct gnutls_cbc_ctx
{
  const struct nettle_cipher *cipher;

  /* A cipher specific context, followed by iv. Use unsigned long as
     an alignment hack (or use pointers and additional memory blocks).
     Total allocation size:

     offsetof (struct gnutls_cbc_ctx, buf)
       + cipher->context_size + cipher->block_size. */
  unsigned long buf[1];
};

void
gnutls_cbc_encrypt (void *p, ...)
{
  struct gnutls_cbc_ctx *ctx = (struct gnutls_cbc_ctx *) p;
  void *cipher_ctx = ctx->buf;
  uint8_t *iv = (uint8_t *) cipher_ctx + ctx->cipher->context_size;
  cbc_encrypt (cipher_ctx, ctx->cipher->encrypt,
               ctx->cipher->block_size, iv, ...);
}
  
and use the same encrypt function for all ciphers in cbc mode. Not sure
what's best, to go this route, or generate boilerplate code for each
algorithm.

And note that the only casting above is for packing everything into the
same memory block, otherwise the cbc_encrypt call needs no casts at all.
(The essential casts are hidden in the initialization of the various
nettle_cipher instances).

> btw. I realized that nettle-meta.h lacks definitions for 3des, des and 
> salsa20.

des and des3 (and blowfish) are missing, because their set_key functions
have a return value indicating weak keys. Maybe they should be added
anyway? Either relying on casting betwen function pointers being safe
with and without return value, or using a wrapper function to explicitly
remove it.

Unfortunately, I don't think a C compiler can optimize

  int bar (int x);
  void foo(int x)
  {
    (void) bar(x); /* Ignore return value */
  }

to make foo simply an alias of bar (assuming the ABI calling ocnventions
allow that). As far as I understand, the C standard requires that &bar
!= &foo, so at best foo wil be compiled into a single jmp instruction.

And salsa20 is missing because there is no nettle-meta abstraction for
stream ciphers. Internally, I use nettle_aead with NULL ->update and
->digest methods to represent stream ciphers, but I'm not sure if that's
suitable for a public interface. BTW, it's of course possible to
represent CBC and CTR mode in the same way, as nettle_aead without
authentication.

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.
_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to