Mailing List Archive

accessing arcfour sboxes
I have an application that uses arcfour, and need to be able to
extract (and set) the (sbox, i, j) tuple. I tried to implement this
in libgcrypt, and noticed the cipher-specific _ctl functions has been
removed, so it does not seem possible to reach each low-level cipher
via gcry_cipher_ctl() any longer, which I miss. The cipher struct now
looks like:

/* Module specification structure for ciphers. */
typedef struct gcry_cipher_spec
{
const char *name;
const char **aliases;
gcry_cipher_oid_spec_t *oids;
size_t blocksize;
size_t keylen;
size_t contextsize;
gcry_cipher_setkey_t setkey;
gcry_cipher_encrypt_t encrypt;
gcry_cipher_decrypt_t decrypt;
gcry_cipher_stencrypt_t stencrypt;
gcry_cipher_stdecrypt_t stdecrypt;
} gcry_cipher_spec_t;

Where the two last entries correspond to stream en/de-cryption (btw,
why does a stream cipher need different encryption/decryption calls?).

Would it be possible to add a 'gcry_cipher_ctl_t ctl', or something,
to that struct, and in the arcfour.c define this to a function that
extract/set the (sbox, i, j)? The gcry_cipher_ctl_t function should
be modeled after gcry_cipher_ctl():

/* Perform various operations on the cipher object H. */
gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
size_t buflen);

So it is able to support various low-level cipher specific stuff.

What do you think of the general idea?

Is there any other way to communicate, from the application, directly
to each low-level cipher object in libgcrypt, that I missed?

Thanks.
Re: accessing arcfour sboxes [ In reply to ]
Simon Josefsson <jas@extundo.com> writes:

> I tried to implement this in libgcrypt, and noticed the
> cipher-specific _ctl functions has been removed,

Sorry, about exactly which functions are you talking here?

> (btw, why does a stream cipher need different encryption/decryption
> calls?).

Hmm, well, the encrypt/decrypt functions of a stream cipher need an
argument that specify the amount of bytes provided, don't they?

> Would it be possible to add a 'gcry_cipher_ctl_t ctl', or something,
> to that struct, and in the arcfour.c define this to a function that
> extract/set the (sbox, i, j)?

Yes, something like that seems to be necessary.

> /* Perform various operations on the cipher object H. */
> gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
> size_t buflen);

I just wonder wether this would be the best interface. How exactly
would you like to call this function? I mean, you somehow have to
pack the data (the S-Box array and two numbers) into a `buffer' and
arcfour.c would have to access this buffer the same way.

I have something like this in mind:

Let Libgcrypt export:

typedef enum gcry_ctl
{
GCRY_CTL_ARCFOUR_CONTEXT_SET,
GCRY_CTL_ARCFOUR_CONTEXT_GET
} gcry_ctl_t;

typedef struct gcry_arcfour_context
{
int i, j;
byte sbox[256];
} gcry_arcfour_context_t;

gcry_error_t gcry_cipher_control (gcry_cipher_hd_t handle,
gcry_ctl_t action,
void *data);

Then the caller could do:

gcry_arcfour_context_t c = { ... };
err = gcry_cipher_control (handle,
GCRY_CTL_ARCFOUR_CONTEXT_SET, &c);

Extending other ciphers this way would mean, one would have to:

* add new `actions' to the gcry_ctl_t list,
* define according types for casting to/from the `void *data'
argument

> Is there any other way to communicate, from the application,
> directly to each low-level cipher object in libgcrypt, that I
> missed?

No, you did not.

What do you think about this, Simon, Werner?

moritz
--
((gpg-key-id . "6F984199")
(email . "moritz@duesseldorf.ccc.de")
(webpage . "http://duesseldorf.ccc.de/~moritz/"))
Re: accessing arcfour sboxes [ In reply to ]
On Sat, 27 Sep 2003 22:38:36 +0200, Moritz Schulte said:

> What do you think about this, Simon, Werner?

I think that Simon's needs are very special and would clutter
Libgcrypt with stuff rarely needed. Especially with the very simple
Arcfour algorithm, a separate implementation - outside of Libgcrypt -
makes sense to me.

Simon, can you give us some hints why you need it?

--
Werner Koch <wk@gnupg.org>
The GnuPG Experts http://g10code.com
Free Software Foundation Europe http://fsfeurope.org
Re: accessing arcfour sboxes [ In reply to ]
Moritz Schulte <mo@g10code.com> writes:

> Simon Josefsson <jas@extundo.com> writes:
>
>> I tried to implement this in libgcrypt, and noticed the
>> cipher-specific _ctl functions has been removed,
>
> Sorry, about exactly which functions are you talking here?

I was wrong, I had been thinking about the gcry_md_info() function in
the old API, which I probably never understood.

So it appears the framework I wanted to use was never implemented, and
in that case I understand Werner's opinion that it complicate matters
for a small gain.

>> (btw, why does a stream cipher need different encryption/decryption
>> calls?).
>
> Hmm, well, the encrypt/decrypt functions of a stream cipher need an
> argument that specify the amount of bytes provided, don't they?

Yes, but encryption and decryption is the same operation for a stream
cipher; "pt XOR stream" vs "ct XOR stream". But this doesn't matter,
really.

>> /* Perform various operations on the cipher object H. */
>> gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
>> size_t buflen);
>
> I just wonder wether this would be the best interface. How exactly
> would you like to call this function? I mean, you somehow have to
> pack the data (the S-Box array and two numbers) into a `buffer' and
> arcfour.c would have to access this buffer the same way.
>
> I have something like this in mind:
>
> Let Libgcrypt export:
>
> typedef enum gcry_ctl
> {
> GCRY_CTL_ARCFOUR_CONTEXT_SET,
> GCRY_CTL_ARCFOUR_CONTEXT_GET
> } gcry_ctl_t;
>
> typedef struct gcry_arcfour_context
> {
> int i, j;
> byte sbox[256];
> } gcry_arcfour_context_t;
>
> gcry_error_t gcry_cipher_control (gcry_cipher_hd_t handle,
> gcry_ctl_t action,
> void *data);
>
> Then the caller could do:
>
> gcry_arcfour_context_t c = { ... };
> err = gcry_cipher_control (handle,
> GCRY_CTL_ARCFOUR_CONTEXT_SET, &c);

Yes, this was exactly what I had in mind! Thanks for understanding my
poor explanation.

> Extending other ciphers this way would mean, one would have to:
>
> * add new `actions' to the gcry_ctl_t list,
> * define according types for casting to/from the `void *data'
> argument

Yes.

Thanks,
Simon
Re: accessing arcfour sboxes [ In reply to ]
Werner Koch <wk@gnupg.org> writes:

> On Sat, 27 Sep 2003 22:38:36 +0200, Moritz Schulte said:
>
>> What do you think about this, Simon, Werner?
>
> I think that Simon's needs are very special and would clutter
> Libgcrypt with stuff rarely needed. Especially with the very simple
> Arcfour algorithm, a separate implementation - outside of Libgcrypt -
> makes sense to me.

I don't disagree with this.

> Simon, can you give us some hints why you need it?

The Kerberos cipher algorithms are specified to take an IV and return
an IV (as well as the actual data to work on), and I have modeled my
API after this. There is a non-standard but allegedly widely used
Kerberos ARCFOUR cipher and some applications appear to support it
(e.g., Kerberos 'rsh'). Since stream cipher doesn't really have an IV
we can't return it. But there is still a need to "carry on" the same
state to the next encryption, which essentially is what IV is about
anyway. So implementations appear to use SBOX + i + j in this
situation as the IV, which would work fine when the crypto API allows
me to extract it.

But copying the ARCFOUR code into my application would work, I guess.

Thanks,
Simon