How to perform a digital signature on Smartcard with prestored hash - digital-signature

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.

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.

Why does ECC signature verification need random numbers (sometimes taking a long time) in OpenSSL 1.1?

I was working on a Linux boot-time (kinit) signature checker using ECC certificates, changing over
from raw RSA signatures to CMS-format ECC signatures. In doing so, I found the
CMS_Verify() function stalling until the kernel printed "crng init done", indicating it needed to wait for there to be enough system entropy for cryptographically secure random number generation. Since nothing else is going on in the system, this took about 90 seconds on a Beaglebone Black.
This surprised me, I would have expected secure random numbers to be needed for certificate generation or maybe for signature generation, but there aren't any secrets to protect in public-key signature verification. So what gives?
(I figured it out but had not been able to find the solution elsewhere, so the answer is below for others).
Through a painstaking debug-by-printf process (my best option given it's a kinit), I found that a fundamental ECC operation uses random numbers as a defense against side-channel attacks. This is called "blinding" and helps prevent attackers from sussing out secrets based on how long computation takes, cache misses, power spikes, etc. by adding some indeterminacy.
From comments deep within the OpenSSL source:
/*-
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
* Since we don't have a Mont structure here, SCA hardening is with blinding.
*/
int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx)
and that function goes on to call BN_priv_rand_range().
But in a public-key signature verification there are no secrets to protect. To solve the problem, in my kinit I just pre-seeded the OpenSSL random number generator with a fixed set of randomly-chosen data, as follows:
RAND_seed( "\xe5\xe3[...29 other characters...]\x9a", 32 );
DON'T DO THAT if your program works with secrets or generates any keys, signatures, or random numbers. In a signature-checking kinit it's OK. In a program that required more security I could have seeded with data from the on-chip RNG hardware (/dev/hw_random), or saved away some entropy in secure storage if I had any, or sucked it up and waited for crng init done.

How does a hash digest update function work? [duplicate]

I have an API route that proxies a file upload from the browser/client to AWS S3.
This API route attempts to stream the file as it is uploaded to avoid buffering the entire contents of the file in memory on the server.
However, the route also attempts to calculate an MD5 checksum of the file's body. As each part of the file is chunked, the hash.update() method is invoked w/ the chunk.
http://nodejs.org/api/crypto.html#crypto_hash_update_data_input_encoding
var crypto = require('crypto');
var hash = crypto.createHash('md5');
function write (chunk) {
// invoked many times as file is uploaded
hash.update(chunk);
}
function done() {
// will hash buffer all chunks in memory at this point?
hash.digest('hex');
}
Will the instance of Hash buffer all the contents of the file in order to perform the hash calculation (thus defeating the goal of avoiding buffering the entire file's contents in memory)? Or can an MD5 hash be calculated incrementally, without ever having the entire input available to perform the calculation?
MD5 and some other hash functions are based on the Merkle–Damgård construction. It supports the incremental/progressive/streaming hashing of data. After the data is transformed into an internal state (which has a fixed size) a last finalization step is performed to generate the final hash by padding and processing the last block and afterwards by simply returning the final state.
This is probably also why many hashing library functions are designed in such a way with an update and a finalization step.
To answer your question: No, the file content is not kept in a buffer, but is rather transformed into a fixed size internal state.
All modern cryptographic hash functions are created in such a way that they can be updated incrementally.
To allow for incremental updates, the input data of the message is first arranged in blocks. These blocks are processed in order. To do this the implementation usually buffers the input internally until it has a full block, and then processes this block together with the current state to produce a new state, using a so called compression function. The initial state usually simply consists of predetermined constant values. During the call to digest the last block is padded - usually with bit padding and an encoding of the amount of processed bytes - and the final state is calculated; this may require an additional block without any message data. A final operation may be performed and finally the resulting hash value is returned.
For MD5 the Merkle–Damgård construction is used. This common construction is also used for SHA-1 and SHA-2. SHA-2 is a family of hashes based on the algorithms for SHA-256 (SHA-224) and SHA-512 (SHA-384, SHA-512/224 and SHA-512/256). MD5 in particular uses a block size of 512 bits and a internal state of 128 bits. The internal state of the last block (including padding) is simply output directly without any post-processing for MD5, SHA-1, SHA-256 and SHA-512.
Keccak has been chosen to be SHA-3. It is construction based on a sponge, a specific compression function. It isn't a Merkle–Damgård hash - which is a big reason why it has been chosen as SHA-3. It still has all the update properties of Merkle–Damgård hashes and has been designed to be compatible with SHA-2. It splits up and buffers blocks just like the previously mentioned hashes, but it has a larger internal state and performs final operations on the output, making it arguably more secure.
So when you were using a modern hash construction such as MD5 you were unknowingly performing additional buffering. Fortunately, the buffering of a single block of 512 bits + 128 bits for the state size will not likely make you run out of memory. It is certainly not required for the hash implementation to buffer the entire message before the final hash value can be calculated.
Notes:
MD5 and SHA-1 are considered insecure w.r.t. collision resistance and they should preferably not be used anymore, especially when it comes to validating contents;
A "compression function" is a specific cryptographic notion; it is not
LSZIP or anything similar;
There may be specialized, theoretical hashes that perform the calculate the values differently - theoretically speaking there is no requirement to split the input messages into blocks and operate on the blocks sequentially. No worry, those are unlikely to be in the libraries you are using;
Similarly, implementations may decide to buffer more blocks at once, but that is fortunately extremely uncommon as well. Commonly only one block is used as buffer - in some cases it could be more performant to buffer a few blocks instead;
Some low level implementations may require you to supply the blocks yourself for reasons of efficiency.

What value for length field for Freescale PowerPC Security Engine 2.0, when using Link Tables?

I am working on the code to use the security engine of my MPC83XX with Openssl.
I can already encrypt/decrypt AES up to 64KByte of data.
The problem comes with data greater than 64KByte since the maximum value of the length-bits is 65535.
I can assume the data is always in one piece on the Ram.
So now I am collecting all the data in a Link Table and use the pointer to the table instead of the pointer to the data and set the J bit to 1.
Now I am not sure what a value I should use for the length-bits since 0 would mean the Dword will be ignored.
The real length of the data is too also big for 16 bit.
http://cache.freescale.com/files/32bit/doc/app_note/AN2755.pdf?fpsp=1
Possible Informations can be found in Chapter 8.
You set LENGTH to the length of the data. See Page 19:
For any sequence of data parcels accessed by a link table or chain of link tables, the combined lengths of the parcels (the sum of their LENGTH and/or EXTENT fields) must equal the combined lengths of the link table memory segments (SEGLEN fields). Otherwise the channel sets the appropriate error bit in the Channel Pointer Status Register...
I'm not sure what mode you're using (and the documentation seems unnecessarily confusing!) but for the usual cipher modes (CBC/CTR/CFB/OFB) the the usual method is simply to chain AES invocations, reusing the same context. You might be able to do this by simply setting "Pointer Dword1" and "Pointer Dword5" to the same thing. There's very little documentation, though; I can't work out where it gets the IV from.

Avoid that repeated same messages look always same after encryption, and can be replayed by an attacker?

I'm looking to authenticate that a particular message is coming from a particular place.
Example: A repeatedly sends the same message to B. Lets say this message is "helloworld" which is encrypted to "asdfqwerty".
How can I ensure that a third party C doesn't learn that B always receives this same encrypted string, and C starts sending "asdfqwerty" to B?
How can I ensure that when B decrypts "asdfqwerty" to "helloworld", it is always receiving this "helloworld" from A?
Thanks for any help.
For the former, you want to use a Mode of Operation for your symmetric cipher that uses an Initialization Vector. The IV ensures that every encrypted message is different, even if it contains the same plaintext.
For the latter, you want to sign your message using the private key of A(lice). If B(ob) has the public key of Alice, he can then verify she really created the message.
Finally, beware of replay attacks, where C(harlie) records a valid message from Alice, and later replays it to Bob. To avoid this, add a nonce and/or a timestamp to your encrypted message (yes, you could make the IV play double-duty as a nonce).
Add random value to the data being encrypted, and whenever it's decrypted, strip it from the original unencrypted data.
You need decent random number generator. I'm sure Google will help you on that.
C noticing that B receives twice the same encrypted message is an issue called traffic analysis and has historically been a heavy concern (but this was in times which predated public key encryption).
Any decent public encryption system includes some random padding. For instance, for RSA as described in PKCS#1, the encrypted message (of length at most 117 bytes for a 1024-bit RSA key) gets a header with at least eight random (non-zero) bytes, and a few extra data which allows the receiver to unambiguously locate the padding bytes, and see where the "real" data begins. The random bytes will be generated anew every time; hence, if A sends twice the same message to B, the encrypted messages will be different, but B will recover the original message twice.
Random padding is required for public key encryption precisely because the public key is public: if encryption was deterministic, then an attacker could "try" potential messages and look for a match (this is exhaustive search on possible messages).
Public key encryption algorithms often have heavy limitations on data size or performance (e.g. with RSA, you have a strict maximum message length, depending on the key size). Thus, it is customary to use a hybrid system: the public key encryption is used to encrypt a symmetric key K (i.e. a bunch of random bytes), and K is used to symmetrically encrypt the data (symmetric encryption is fast and does not have constraints on input message size). In a hybrid system, you generate a new K for every message, so this also gives you the randomness you need to avoid the issue of encrypting several times the same message with a given public key: at the public encryption level, you are actually never encrypting twice the same message (the same key K), even if the data which is symmetrically encrypted with K is the same than in a previous message. This would protect you from traffic analysis even if the public key encryption itself did not include random padding.
When symmetrically encrypting data with a key K, the symmetric encryption should use an "initial value" (IV) which is randomly and uniformly generated; this is integrated in the encryption mode (some modes only need a non-repeating IV without requiring a random uniform generation, but CBC needs random uniform generation). This is a third level of randomness, protecting you against traffic analysis.
When using asymmetric key agreement (static Diffie-Hellman), since are a bit more complex, because a key agreement results in a key K which you do not choose, and which could be the same ever and ever (between given sender and receiver). In that situation, protection against traffic analysis relies on the symmetric encryption IV randomness.
Asymmetric encryption protocols, such as OpenPGP, describe how the symmetric encryption, public key encryption and randomness should all be linked together, ironing out the tricky details. You are warmly encouraged not to reinvent your own protocol: it is difficult to design a secure protocol, mostly because one cannot easily test for the presence or absence of any weakness.
You may want to study block cipher modes of operation. However, the modes are designed to work on a data stream that is sent over a reliable channel. If your messages are sent out of order over an unreliable transport (e.g. UDP packets), I don't think you can use it.

Resources