OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

pkcs11 message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: [pkcs11] CK_ULONG considered harmful?


On 05/20/2013 06:02 PM, Chris Zimman wrote:
...
For example:  You have a remote token, say a network HSM -- how is it supposed to deal with CK_ULONG if it gets values that a 64 bits in some cases and 32 bits in others?  What does it do if a client that treats CK_ULONG as 32 bits requests an object (say a CKA_TOKEN object) that was created by something where CK_ULONG was 64 bit?  Clearly it's not going to work, but the spec doesn't currently have a way to deal with this case.  Also, what is a token that's 32 bit internally supposed to do with a value that's sent from a 64 bit CK_ULONG client?

These issues inevitably will come up in network protocols. It's quite a common issue.

The server (HSM) will know the exact definition of the CK_ULONG that the client uses. The client-side PKCS#11 library will pass this information to the server (due to the 1:1 match of the library to the architecture that I described in the previous e-mail).

The entire set of related problems can be split into the two categories:

1. The value in question actually fits the range of [0,2^32], i.e. whether one always has (unsigned)x == (unsigned long long)x regardless of how much memory x takes. It's then just a matter of casting and using the right type internally. For example, the system that does the processing on 32 bit system is expected to use the a 32 bit working value for efficiency/simplicity. 64 bit arithmetic will incur unnecessary overhead, compiler warnings, etc.

I do believe that any standard would benefit from specifying the valid range of each field, in particular, whether the type is allowed to exceed 2^32.

2. The value may exceed 2^32. Then the truncation is possible and this can be an error in some (rare) cases.

One should try to avoid #2. There are two ways to do so: the standard can do its part and applications/implementation can help regardless of the recognition of this issue by the standard.

If these are enumerations, flags fields, the values should be constrained to the lower 32 bits by the standard (or the standard is broken on 32 bit systems).

HANDLEs (as pointers) are not network-portable and must be re-mapped, so that seems fine. If implementation needs portability of things like CK_SLOT_ID, it should maintain it under the 2^32.

One legitimate example where the value > 2^32 is the length of a plaintext/ciphertext buffers (capping the PIN length at 2^32 seems fine). Hypothetically, the marshalling layer can split buffers > 2^32 into chunks when the host cannot handle the large buffer. These buffers must be pumped over the network in presumably packets that are smaller than 2^32 anyway. Perhaps the standard can specify that if you want to reliably handle buffers >= 2^32, you must process them in chunks < 2^32 with operations like C_EncryptUpdate.


In summary, it seems that the problem is quite constrained in PKCS#11. IMO what needs to happen is to
1) define CK_ULONG as size_t
2) identify the cases where the legitimate value > 2^32 and what to do in these cases.

It possible that we leave 1) as it is. Windows suffers then as it then becomes always a 32 bit size system. It is possible that the set of 2) is zero, i.e. we say that no length can take the value > 2^32 and the application code must do *Update type of invocation to process larger lengths.

Other alternatives that don't work IMO:
*) fix CK_ULONG at 32 or 64 bit. POSIX, STL, etc use size_t and the compatibility between CK_ULONG and size_t is then an issue pushed up to the caller.




[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]