Dr Stephen Henson wrote:
>
> I'm not clear on a number of points. I think the easiest way to
> handle this is to give some of the requirements of the EVP interface
> (not all of which work properly at present) and you can see if that fits
> in with your proposal.
Good idea, since I am quite sure that I did not catch all requirements
from
you post from the beginning of february. My main aim is to make it work
with PKCS#11, but I will see that any requirements you throw my way are
included in a sensible fashion
>
> Heres the first requirement...
>
> The symmetric cipher code must have some cipher independency in fact it
> should have a lot. The reason for this is so the EVP_Seal/EVP_Open stuff
> can work properly. It doesn't currently work properly and can't work
> properly under the current system which is one reason the EVP interface
> needs an overhaul.
>
> EVP_Open will typically decrypt an RSA block using a private key. Its
> output will be a key and a key length. The key length is the current
> sticking point.
>
> The actual cipher to use will be determined by other means. One such
> method is via an ASN.1 AlgorithmIdentifier defined as follows:
>
> AlgorithmIdentifier ::= SEQUENCE {
> algorithm OBJECT IDENTIFIER,
> parameters ANY DEFINED BY algorithm OPTIONAL }
>
> The "algorithm" object defines the cipher type and the "parameters"
> define any cipher specific info.
For this I propose a
EVP_CIPHER EVP_getcipherbyASN1(unsigned char* asn1_string, unsigned
int lenght)
function that decodes the ASN.1 string and uses the cipher list to look
up
the cipher by its OID, calling the _ext method with all he additional
parameters. This function sits on top of the functions that I outlined
in my
fist post.
>
> The "algorithm" object is the NID part of the cipher. In the examples
> I'm aware of there is only one NID per cipher type. That is there is
> only one RC2 and RC4 object. This immediately shows how the current code
> is broken.
Ok, that is good to know. NID_rc4_40 will go out the window and I will
look at
rc2 a bit more.
>
> So what you have is this: a key, a key length, a NID giving the cipher
> type and some ASN.1 parameters which give cipher specific info.
Which is sufficient to have the proper method create a specific cipher,
instantiated
with all the parameters in place.
>
> Now in the cases of some ciphers like DES-CBC and 3DES-CBC the
> 'parameters' only contain the IV. In the case of RC4 it doesn't contain
> anything at all. In the case of RC2 it contains an indication of the
> effective key length and the IV.
Why do you want to set the IV from the ASN.1 params. It is a param to
the
EVP_{En|De}cryptInit() functions. Or do you mean the iv-length?
>
> For ciphers with a fixed key length (DES, 3DES) if the key length is
> anything other than that fixed value it is an error.
hmmm, I was planing on ignoring anything that is not valid. Thus you
would
have des and 3des simply have their key lentgh set and ignore any call
to
change it. One less thing to check for in case of an error.
>
> For variable key length ciphers this determines the actual key length,
> for example RC2, RC4: this is not handled at present. In fact it can't
> be handled at present because the current EVP stuff only provides a
> small number of ciphers with fixed key lengths: if your key length isn't
> one of the list your are out of luck.
That is exactly what my proposal changes. The old functions still work
because
they give the old defaults to the <cipher>_ext() functions, thus
maintaining
backward compatibility. There are some special cases where those
functions
are removed (EVP_rc4_40() being one), as they no longer are needed and
can
be clean up to remove those arbitrary NID and special case ciphers.
>
> Now what you should be able to do is have an interface where EVP_Open
> contains no symmetric cipher specific code (it doesn't at present but it
> doesn't work properly either).
It will not. The EVP_CIPHER structure includes all info including the
needed methods and may be created either from calling the applicable
EVP_<cipher>_ext() function or by calling the function outlined above
that will parse an ASN.1 string. That will present you with a custom
made EVP_CIPHER structure that you can supply to any of the functions
that take them right now.
>
> The reverse side of things is that you should be able to generate
> this ASN.1 stuff. EVP_Seal shouldn't have any cipher specific code
> either but the user will obviously need to call some cipher specific
> code with the relevant parameters and get the ASN.1 stuff out.
Encoding exactly what? I must admint that I am still a bit shaky on
the details on where to use ASN.1 and where not to do so. But in
principle
all cipher specific stuff should go into the methods supplied by the
EVP_CIPHER.
>
> This is all much easier if you do allow EVP_Open to contain cipher
> specific code.
Never! B-)
>
> However if you don't have EVP_Open contain cipher specific code then you
> get some algorithm independency.
>
> Suppose someone writes a brand new cipher, this cipher might be
> implemented in hardware for example.
>
> If the EVP_Open/EVP_Seal interface works properly this wont matter. As
> soon as the new algorithm is added it will automatically be supported:
> it would register a NID and contain some ASN.1 code.
>
> What EVP_Open should be able to do is look up the new cipher by its NID
> and then use its various functions to decode the ASN.1 stuff and set the
> key and key length. It should then be able to give an error or a
> properly initialised cipher context structure.
>
> Now *every* cipher doesn't need to fit in this model, some might not
> want anything to do with this ASN.1 stuff some might not have any ASN1
> stuff registered.
>
> How this fits in with PKCS#11 is a bit more ambiguous.
>
> It can be handled directly where the key and key length come from
> EVP_Open and the other object attributes come from the NID and algorithm
> identifier: you'd need an "ASN.1 wrapper" round a PKCS#11 algorithm for
> this to work. You'd typically decrypt the key block and then build up a
> PKCS#11 object with all the bits.
I am not sure I can follow the last paragraph. There is no specific
PKCS#11
algortihm. It basicly needs to work with all the ciphers and pkey, as
the
token might support just about any of them in hardware.
The Open/Seal functions just create the symetric key and then call the
proper encrypt function in each of the pkeys supplied. I see no need for
any asn.1 stuff. It is all covered in the creation of the EVP_PKEY
structures
that are passed to the function.
>
> Alternatively you could have a PKCS#11 mechanism partially override the
> EVP_Open interface and call C_Unwrap. This has the advantage that the
> unwrapped key never leaves the PKCS#11 library and is never directly
> visible to the user, or more importantly an attacker. EVP_Seal could be
> handled similarly.
C_Wrap/C_Unwrap are the proper encryptin functions. But since EVP does
not
know the concept of a wrap and only contains a encrypt function, I might
handle the symetric key as any other data.
the key may only remain in the token if a) the token supports symetric
operations which I cannot take for granted at all and b) I can get
EVP to handle 'pseudo-keys' in a clean way. I have not yet a concept for
this. But as the symetric key for a Open/Seal operation is a session key
only it is not a very valuable target for an attack and I don't think
it nessecary to concentrate on that now.
mfg lutz
--
*******************************************************************
Lutz Behnke Tel.: 040 / 766 29 1423
TC TrustCenter for Security Fax.: 040 / 766 29 577
in Data Networks GmbH email: [EMAIL PROTECTED]
Am Werder 1
21073 Hamburg, Germany
S/MIME Cryptographic Signature