808bits

CKR_DATA_LEN_RANGE

PKCS#11 return value · 0x00000021 · decimal 33
hex 0x00000021 decimal 33 name CKR_DATA_LEN_RANGE

The library or the token checked the byte count of your input against the mechanism before doing any work, and the count failed. Three shapes cover most reports: a block cipher fed a partial block with padding off, an RSA operation given more than a modulus worth of data, and a raw signing mechanism handed a document where it wanted a digest. Nothing was encrypted or signed.

What the token is reporting

The plaintext, message or derivation data has a length the mechanism does not accept. This is a check on the count alone. A well-formed count with malformed content is a different code.

Likely causes

Ordered by how often they turn out to be the answer. That ordering is a judgement from experience, not a measured frequency.

ECB or CBC without padding and a length that is not a block multiple

CKM_AES_CBC and CKM_AES_CBC_PAD are different mechanisms and only the second one pads. Code that picks the unpadded one, or a wrapper whose default is the unpadded one, works for sixteen-byte test vectors and fails on real data.

Check it: Take the input length modulo the block size. A non-zero remainder with an unpadded mechanism is the whole story.

Fix: Use the padded variant, or pad to the block size yourself and strip it after decryption.

RSA input longer than the modulus allows

CKM_RSA_PKCS takes at most the modulus length minus eleven bytes, OAEP less than that depending on the hash, and CKM_RSA_X_509 at most the modulus length. Encrypting a whole message with RSA rather than a key hits this at the first real payload.

Check it: Compare the input length with CKA_MODULUS_BITS divided by eight, minus the mechanism’s overhead.

Fix: Encrypt a symmetric key with RSA and the data with that key, which is what every protocol does.

A raw mechanism handed a whole message instead of a digest

CKM_DSA and CKM_ECDSA take a digest, and CKM_RSA_PKCS used for signing expects a DigestInfo that fits in the modulus. Passing the document itself, which the hash-combined mechanisms accept happily, is rejected on length here.

Check it: Check whether the mechanism name contains a hash. If it does not, the input has to be digest-sized.

Fix: Use CKM_SHA256_RSA_PKCS, CKM_ECDSA_SHA256 or the equivalent, and let the token hash.

The token, not the library, said wrong length

Smart card libraries translate the card’s wrong-length status word into this code, and network HSM libraries do the same for their own length errors. It can then come from any command whose length field the device disliked, including ones that are not data operations.

Check it: Turn on the library’s debug log and read the native error or status word beneath the code.

Which calls return it

C_Encrypt, C_EncryptUpdate, C_Sign, C_SignRecover, C_Verify, C_DeriveKey

What it is not

It is not the output buffer, which is CKR_BUFFER_TOO_SMALL, and it is not corrupted content, which is data invalid or encrypted data invalid. The count is the only thing that was checked.

Often confused with

  • CKR_BUFFER_TOO_SMALL: Input versus output. This code is about what you passed in, that one is about the room you gave the library to write the answer.
  • CKR_DATA_INVALID: The next check along. The length was fine and the content was not.
  • CKR_ENCRYPTED_DATA_LEN_RANGE: The same check on the decrypt side. Ciphertext with a bad length gets the encrypted variant.
  • CKR_MECHANISM_PARAM_INVALID: If the length rule depends on a parameter, an IV or a tag length, the library may report the parameter rather than the data.

By library

SoftHSMv2

Block ciphers without padding are checked for a remainder before any work, and a second check enforces the cipher’s maximum byte count (Soft HSM.cpp).

IBM opencryptoki

AES ECB and CBC check the input against the block size ([mech_aes.c](ht tps://github.com/opencryptoki/opencryptoki/blob/430a47d7478236891ff174d 096b55e04026981a8/usr/lib/common/mech_aes.c#L46-L48)). The interesting case is the inverse: on RSA decryption a length error from the token layer is rewritten to encrypted data invalid in constant time, so that the code cannot serve as a padding oracle (mech_rsa.c).

OpenSC

The card’s wrong-length status word is translated into this code (misc .c), so it can arise from any APDU the card thought was the wrong size, not only from data operations.

YubiHSM 2

Both the library’s own wrong-length error and the device’s map here (util_pkcs11.c).

Sources

Every description, cause and check on this page is written from scratch. The specification is cited for the constant's name and its number, which are facts, and for nothing else.