Why is the AES-key in gcm-mode 4 bytes longer? - linux

I'm using ip xfrm under Linux to add an IPsec SA with AES in GCM mode to the system.
The command I'm using is like this:
ip xfrm state add src 10.66.21.164 dst 10.66.21.166 proto esp spi 0x201 mode transport aead "rfc4106(gcm(aes))" 0x010203047aeaca3f87d060a12f4a4487d5a5c335 96
Now I'm wondering:
The key is seemingly 20B = 160b long. The normal AES key is 128b and, as can be seen above, the IV-length is 96b. If I lengthen or shorten the key it doesn't work, so clearly the expected input is (sizeof(AES)=128b) (it does, of course, work with 256b too) + 32b long.
Why is this so? The only thing I know that is 4B long in this context is unsigned int, which is the data type of IV-length variable, but this has nothing to do with the key.
Shouldn't the key plus IV be 224b long (128 + 96 for the IV)?

The 96 value in your command is the size of the authentication tag. The authentication tag is part of a message in the session, it is not something you have to specify. The same thing goes for the IV, it is generated by the protocol per message.
The key material consists of a 16 byte (128 bit) AES key and a 4 byte (16 bit) salt in hexadecimal format, which uses 2 characters per byte.
The KEYMAT requested for each AES-GCM key is 20 octets. The first
16 octets are the 128-bit AES key, and the remaining four octets
are used as the salt value in the nonce.
Source: RFC 4106.

Related

AES encryption constant input and output size

I have a key for AES encryption and I'm trying to encrypt strings with constant length as well, does the resultant encrypted string will always have the same length?
That depends on what you mean by 'the same length'.
The same length as the original string: generally no; the original string will be padded to a multiple of the cipher block-length. Check padding modes for details.
The same length every time you encrypt: yes; as long as you stick to the same mode and padding the encrypted output will have the same length.
First of all, a block cipher requires a full block to encrypt, therefore AES requires 16-byte ( or 128-bit ) input to encrypt will output 16-byte ciphertext. This is always the case for block ciphers since they are Pseudo-Random Permutations (PRP) - they are always permutations we expect them to be PRP.
Block ciphers, like AES, are primitives and must be used with a proper mode of operation. Here we will talk only about some of them.
ECB mode is the default and insecure.
Padding: In the case of the message size is not a multiple of the 128, we apply padding. There are various paddings, however, the most common one is the PCKS#7 ( update of PCKS#5 that was for 64-bit block ciphers like DES). This padding append characters to the end so that the size is multiple of 128.
Therefore; the appended number of characters for ECB mode can be from 1 to 16 ( if the block size is already a multiple of 128) then a new block is added with 16 10 bytes.
CBC mode requires a random and unpredictable IV so that we can achieve probabilistic encryption. As in ECB, it requires padding.
Therefore; the appended number of characters for CBC mode can be from 1+16 to 32 since we need to add the IV to the ciphertext.
CTR mode requires Initial Value (IV) that can be random or deterministic. CTR mode converts a block cipher (PRP) into a stream cipher. The plaintext is x-ored with the ciphertext where the input was the IV and incremented for each encryption. There is no need for padding in CTR mode.
Therefore; the appended number of characters for CTR mode is (at most)16.
AAED: The above are archaic mode of operations and today we use Authenticated Encryption (with Associated Data) (AE/AEAD). Unlike the archaic modes, these modes can provide us not only confidentiality but also integrity and authentication.
The authentication part requires a tag (MAC tag) and this really depends on the scheme.
AES-GCM is the NIST-approved mode. AES-GCM's recommended IV size 12 since different size requires an additional process. It always produces a 16-byte tag, however, one can reduce the size of the tag if they want to, although not recommended.
At first one might consider that the size is incremented by 12-16, however, it is not. The GCM always used Associated Data (AD) and allows zeroAD and the size of the AD is always added. For details, see NIST GCM specification
This was the short story of the long list of how the mode of operations behaves in terms of input vs output length.
If you omit the IV size, it is possible with CTR mode.

Converting 45 byte shared key in pynacl to 32 byte key to use along with AES-CBC with 25 byte IV

I am currently working on pynacl library. The problem is I need to use the 45 byte shared key generated to be used to decrypt an AES-CBC encryption with an 25 byte IV. But the AES-CBC can only take 16/24/32 byte keys and 16 byte IV. Can anyone give me some suggestions on how to convert the 45 byte key to 32 bytes and the 25 byte IV to 16 bytes size.

How to perform a digital signature on Smartcard with prestored hash

I am trying to use a smart card to perform a digital signature, my issue is when I try these set of commands:
Select Application: 00A4040410E828BD080F*********
Verify Pin: 0020008506*******
Set SE for CRT HT: 002241AA03800110
Set SE for CRT DST: 002241b606800112840105
Store Hash: 002a90a00890008004AAAAAAAA // AAAAAAAA are Just a random 4 bytes for the card to compute then store
Sign: 002a9e9a00
I can not sign neither by setting the security environment to CRT-DST nor CRT-HT, with the former it returns 6a88(SE problem) and the latter returns 6a95(Hash not found).
I am following IAS_ECC_v1.0.1 to the book but it is not clear which security environment to use in case of setting the hash then signing. I tried the commands for SHA-256 as well but same result.
I am used to setting the security environment then performing the digital signature but this is the first time I encounter the prestored hash type of card.
To clarify at least some issues: What you are describing is not a precomputed hash, but an intermediate hash value, as typically applied in the scheme, where the card has at least some influence in the hash computation. It is supposed to update the given intermediate hash by considering the last data bytes given. This is a sort of middle point between the card hashing all the input data (possible, but due to limited I/O bandwith seldom attractive) and providing the final hash value from the outside (no influence by the card).
Such an intermediate hash requires in DO 90 the intermediate hash value concatenated with a bit counter, which is 8 bytes long. For SHA-256 this would mean 40 bytes (32 bytes hash followed by bit counter). This is combined with DO 80 giving the final data.
Your example (store hash is at least a misleading term), provides the DO 90 as empty, however, contradicting the intention of an intermediate hash.

When deciphering with RC4, what does it mean to skip bytes?

I have the binary data that I need to decipher, the algorithm (RC4) and the key. However, to decipher the data, one instruction I got is that "the length of the key initially gets skipped" or that "len bytes are skipped initially".
What does this mean exactly? Does it mean that if my key is 10 bytes long, that I need to pass in the binary data without the first 10 bytes to the decipher and then concatenate the first 10 bytes with the deciphered bytes?
const decipher = crypto.createDecipheriv('RC4', 'mysuperkey', null);
const buffer = decipher.update(data.slice('mysuperkey'.length));
decipher.final();
This does not work, so I might not understand the instruction.
RC4 is insecure for the first bits, so often you are instructed to skip over some initial bytes of the key stream. The way a stream cipher works is that it creates a stream of pseudo random data that depends on the key. That stream is XOR'ed with the plaintext to create the ciphertext, and with the ciphertext to create the plaintext.
To skip a number of bytes of the key stream you can simply encrypt / decrypt some (zero valued) bytes and throw away the results. This goes both for encryption and decryption. If the API has a specific skip method then you should of course use that, but I don't think it is present in CryptoJS.

pcks5 padding

I have text with 20 octets and 32 octets. So the first one is a complete 16 bytes block and 32 octets is 26 bytes. When I encrypt the file used aes-cbc mode the padding will not be done for the first one, but the padding will be done for the 2nd one. Which is the number of zeros that should be put to make it 32. i.e., the 32th byte will be 5 and the rest of them are zeros. When I encrypted the file with the key.. I have some cipher text.
My question is since from 27-31 are zeros, when the text is encrypted should the algorithm give me the same cipher text between 27-31. Or how will I know that the zeros are added and 5 is the 32nd byte in the text since the value is encrypted.
Correct me if i am wrong..
According to RFC2898 - which defines the PKCS#5 padding - the padding contains in each byte the length of the padding (in bytes). Therefore if you read the last byte of the last decrypted block you received, you will find the information how many padding bytes you can discard.

Resources