KDF and PRF in GlobaPlatform SCP 03 - javacard

I want to implement Globalplatform SCP 03 protocol in javacard. The main problem is KDF and PRF implementation in card. I have three question:
Is there any opensource implementation of KDF and PRF in javacard?
I found "RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);". there is 3 and 4 input for PRF function in NIST sp 800-108, but i can set only one parameter for RandomData in javacard (only seed). is it implementation of PRF?
Does PRF with same inputs, generates same result in different execution? if answer is no, why card and host can generate same session keys by using it?
Thank you very much.
Mohsen

I want to implement Globalplatform SCP 03 protocol in javacard
That's nice, but you know that you can already use the secure messaging channel though the Global Platform API, right? So you would only do this if you would like an identical channel after personalization of the card. It may of course be that your particular card only supports the old 3DES based protocols.
Is there any opensource implementation of KDF and PRF in javacard?
Well, not a KDF, but constructing a KDF from a PRF isn't that hard. And of PRF's there are a few already included: any MAC is a PRF, including HMAC-SHA1. However, GP SCP 03 uses AES CMAC with specific input parameters as KDF.
Basically a hash function or MAC is a poor mans KDF without the input parameters explicitly specified. But for that you read the Global Platform specifications.
I found "RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);". there is 3 and 4 input for PRF function in NIST sp 800-108, but i can set only one parameter for RandomData in javacard (only seed). is it implementation of PRF?
No, a seeded PRNG is not a PRF and you can only add seed info to most implementations, not re-seed the PRNG completely. But again, you need a specific KDF: AES-CMAC, not any kind of KDF for SCP 03.
Does PRF with same inputs, generates same result in different execution? if answer is no, why card and host can generate same session keys by using it?
Yes, of course it does, as long as it doesn't have a random state in the first place, like the random number generators. A non-determinstic PRF would be pretty useless.

Related

Secret vs. Non-secret Initialization Vector

Today I was doing some leisurely reading and stumbled upon Section 5.8 (on page 45) of Recommendation for Pair-Wise Key Establishment Schemes Using Discrete Logarithm Cryptography (Revised) (NIST Special Publication 800-56A). I was very confused by this:
An Approved key derivation function
(KDF) shall be used to derive secret
keying material from a shared secret.
The output from a KDF shall only be
used for secret keying material, such
as a symmetric key used for data
encryption or message integrity, a
secret initialization vector, or a
master key that will be used to
generate other keys (possibly using a
different process). Nonsecret keying
material (such as a non-secret
initialization vector) shall not be
generated using the shared secret.
Now I'm no Alan Turing, but I thought that initialization vectors need not be kept secret. Under what circumstances would one want a "secret initialization vector?"
Thomas Pornin says that IVs are public and he seems well-versed in cryptography. Likewise with caf.
An initialization vector needs not be secret (it is not a key) but it needs not be public either (sender and receiver must know it, but it is not necessary that the Queen of England also knows it).
A typical key establishment protocol will result in both involve parties computing a piece of data which they, but only they, both know. With Diffie-Hellman (or any Elliptic Curve variant thereof), the said shared piece of data has a fixed length and they have no control over its value (they just both get the same seemingly random sequence of bits). In order to use that shared secret for symmetric encryption, they must derive that shared data into a sequence of bits of the appropriate length for whatever symmetric encryption algorithm they are about to use.
In a protocol in which you use a key establishment algorithm to obtain a shared secret between the sender and the receiver, and will use that secret to symmetrically encrypt a message (possibly a very long streamed message), it is possible to use the KDF to produce the key and the IV in one go. This is how it goes in, for instance, SSL: from the shared secret (called "pre-master secret" in the SSL spec) is computed a big block of derived secret data, which is then split into symmetric keys and initialization vectors for both directions of encryption. You could do otherwise, and, for instance, generate random IV and send them along with the encrypted data, instead of using an IV obtained through the KDF (that's how it goes in recent versions of TLS, the successor to SSL). Both strategies are equally valid (TLS uses external random IV because they want a fresh random IV for each "record" -- a packet of data within a TLS connection -- which is why using the KDF was not deemed appropriate anymore).
Well, consider that if two parties have the same cryptographic function, but don't have the same IV, they won't get the same results. So then, it seems like the proposal there is that the two parties get the same shared secret, and each generate, deterministically, an IV (that will be the same) and then they can communicate. That's just how I read it; but I've not actually read the document, and I'm not completely sure that my description is accurate; but it's how I'd start investigating.
IV is public or private, it doesn't matter
let's consider IV is known to attacker, now by looking at encrypted packet/data,
and knowledge of IV and no knowledge on encryption key, can he/she can guess about input data ? (think for a while)
let's go slightly backwards, let's say there is no IV in used in encryption
AES (input, K)= E1
Same input will always produce the same encrypted text.
Attacker can guess Key "K" by looking at encrypted text and some prior knowledge of input data(i.e. initial exchange of some protocols)
So, here is what IV helps. its added with input value , your encrypted text changes even for same input data.
i.e. AES (input, IV, K)= E1
Hence, attacker sees encrypted packets are different (even with same input data) and can't guess easily. (even having IV knowledge)
The starting value of the counter in CTR mode encryption can be thought of as an IV. If you make it secret, you end up with some amount of added security over the security granted by the key length of the cipher you're using. How much extra is hard to say, but not knowing it does increase the work required to figure out how to decrypt a given message.

finding a generator for elgamal

how are generators found for the elgamal signature scheme? are there values that are used by most programs that are good generators? or is there a method to find a generator for a prime value? if so, how? Would it be true to say that a prime number has at least 1 generator?
Use DSA instead of the ElGamal signature scheme.
There are just too many mistakes that can be made implementing ElGamal. One of those mistakes is what GregS proposed: to use the IKE parameters. These parameters were generated for the ElGamal encryption and not for the signature scheme. The two schemes have distinct requirements. In particular using g=2 as a generator is a good choice for the encryption, but a very bad choice for the signature scheme. (See e.g. the "Handbook of Applied Cryptography" http://www.cacr.math.uwaterloo.ca/hac/ note 11.67 in chapter 11 for some details). Correct would be to select the generator randomly. But once again, if you just use DSA then you can simply avoid these pitfalls by following the standard.
Just to add a little more: OpenPGP https://www.rfc-editor.org/rfc/rfc4880 used to allow ElGamal signatures, but has deprecated them some time ago. This deprecation was quite reasonable, since DSA has only advantages: it is more efficient, more secure and standardized. Of course, you could look at old PGP implementations, but it wouldn't tell you if these implementations give you reasonable choices without reading the literature first.
how are generators found for the elgamal signature scheme?
are there values that are used by most programs that are good generators?
or is there a method to find a generator for a prime value? if so, how?
You can use the generic, probabilistic algorithm 4.86 in Handbook of Applied Cryptography. You still need to weed out from the output of such algorithm the values known to be insecure for Elgamal signature though. At the very least any value that divides p-1 (for instance 2) and any value whose inverse divides p-1. Note that those are the conditions I am aware of today. Some in-depth research over papers published on the topic may be needed.
Personally, I would not trust domain parameters already used in existing programs. The authors may not have considered all the conditions above, plus research may have highlighted new conditions since they were chosen.
Would it be true to say that a prime number has at least 1 generator?
Absolutely true: there always is at least one generator for the multiplicative group over the integers modulo p (with p being a prime number). It has actually many more: phi(phi(p)), with phi being the totient function. Not all of them will be safe for the Elgamal signature scheme though.
El Gamal can be seen as a variant of the Diffie Hellman algorithm, and parameters for the latter can be used for the former. So for example you can use IKE groups 1 and 2 from RFC 2409, and larger IKE groups sprinkled in other RFCs. You can also follow the discussion in FIPS 186 for generating DSA parameters. Also, see this discussion of primitive roots.
EDIT:
As noted by #abc, this is wrong for el gamal signatures. Follow the DSA link (FIPS 186).

Security of Exclusive-OR (XOR) encryption

XOR encryption is known to be quite weak. But how weak is it if I have a key that is made up of multiple keys of different (ideally prime) lengths which are combined to make a longer key. eg I have a text keys of length 5, 9 and 11. If I just apply the first key using XOR encryption then it should be easy to break as the encryption byte will repeat every 5 bytes. However if I 'overlay' the 3 of these keys I get an effective non-repeating length of 5*9*11 = 495. This sounds to me pretty strong. If I use a couple of verses of a poem using each line as a key then my non-repeating length will be way bigger than most files. How strong would this be (providing the key remains secret! :) )
XOR encryption is exactly as strong as the key stream. If you XOR with a "One time pad" - a sequence of physically generated random numbers that you only use once, then your encryption is theoretically unbreakable. You do have the problem however of hiding and distributing the key.
So your question comes down to - "how secure/random is a keystream made of three text strings?" The answer is "not very secure at all". Probably good enough to keep out your little sister, but not necessarily if you've got a smart little sister like I have.
What about the 'known plaintext' attack? If you know the encrypted and the cleartext versions of the same string, you can retrieve the key.
http://en.wikipedia.org/wiki/XOR_cipher
http://en.wikipedia.org/wiki/Known-plaintext_attack
http://en.wikipedia.org/wiki/Stream_cipher_attack
If P and Q are two independent cryptographic methods, the composite cryptographic function P(Q(x)) won't be any weaker than the stronger of P(x) or Q(x), but it won't necessarily be meaningfully stronger either. In order for a composite cryptographic function to gain any strength, the operations comprising it have to meet certain criteria. Combining weak ciphers arbitrarily, no matter how many one uses, is unlikely to yield a strong cipher.

Random access encryption with AES In Counter mode using Fortuna PRNG:

I'm building file-encryption based on AES that have to be able to work in random-access mode (accesing any part of the file). AES in Counter for example can be used, but it is well known that we need an unique sequence never used twice.
Is it ok to use a simplified Fortuna PRNG in this case (encrypting a counter with a randomly chosen unique key specific to the particular file)? Are there weak points in this approach?
So encryption/decryption can look like this
Encryption of a block at Offset:
rndsubseq = AESEnc(Offset, FileUniqueKey)
xoredplaintext = plaintext xor rndsubseq
ciphertext = AESEnc(xoredplaintext, PasswordBasedKey)
Decryption of a block at Offset:
rndsubseq = AESEnc(Offset, FileUniqueKey)
xoredplaintext = AESDec(ciphertext, PasswordBasedKey)
plaintext = xoredplaintext xor rndsubseq
One observation. I came to the idea used in Fortuna by myself and surely discovered later that it is already invented. But as I read everywhere the key point about it is security, but there's another good point: it is a great random-access pseudo random numbers generator so to speak (in simplified form). So the PRNG that not only produces very good sequence (I tested it with Ent and Die Hard) but also allow to access any sub-sequence if you know the step number. So is it generally ok to use Fortuna as a "Random-access" PRNG in security applications?
EDIT:
In other words, what I suggest is to use Fortuna PRNG as a tweak to form a tweakable AES Cipher with random-access ability. I read the work of Liskov, Rivest and Wagner, but could not understand what was the main difference between a cipher in a mode of operation and a tweakable cipher. They said they suggested to bring this approach from high level inside the cipher itself, but for example in my case xoring the plain text with the tweak, is this a tweak or not?
I think you may want to look up how "tweakable block ciphers" work and have a look at how the problem of disc encryption is solved: Disk encryption theory. Encrypting the whole disk is similar to your problem: encryption of each sector must be done independently (you want independent encryption of data at different offsets) and yet the whole thing must be secure. There is a lot of work done on that. Wikipedia seems to give a good overview.
EDITED to add:
Re your edit: Yes, you are trying to make a tweakable block cipher out of AES by XORing the tweak with the plaintext. More concretely, you have Enc(T,K,M) = AES (K, f(T) xor M) where AES(K,...) means AES encryption with the key K and f(T) is some function of the tweak (in your case I guess it's Fortuna). I had a brief look at the paper you mentioned and as far as I can see it's possible to show that this method does not produce a secure tweakable block cipher.
The idea (based on definitions from section 2 of the Liskov, Rivest, Wagner paper) is as follows. We have access to either the encryption oracle or a random permutation and we want to tell which one we are interacting with. We can set the tweak T and the plaintext M and we get back the corresponding ciphertext but we don't know the key which is used. Here is how to figure out if we use the construction AES(K, f(T) xor M).
Pick any two different values T, T', compute f(T), f(T'). Pick any message M and then compute the second message as M' = M xor f(T) xor f(T'). Now ask the encrypting oracle to encrypt M using tweak T and M' using tweak T'. If we deal with the considered construction, the outputs will be identical. If we deal with random permutations, the outputs will be almost certainly (with probability 1-2^-128) different. That is because both inputs to the AES encryptions will be the same, so the ciphertexts will be also identical. This would not be the case when we use random permutations, because the probability that the two outputs are identical is 2^-128. The bottom line is that xoring tweak to the input is probably not a secure method.
The paper gives some examples of what they can prove to be a secure construction. The simplest one seems to be Enc(T,K,M) = AES(K, T xor AES(K, M)). You need two encryptions per block, but they prove the security of this construction. They also mention faster variants, but they require additional primitive (almost-xor-universal function families).
Even though I think your approach is secure enough, I don't see any benefits over CTR. You have the exact same problem, which is you don't inject true randomness to the ciphertext. The offset is a known systematic input. Even though it's encrypted with a key, it's still not random.
Another issue is how do you keep the FileUniqueKey secure? Encrypted with password? A whole bunch issues are introduced when you use multiple keys.
Counter mode is accepted practice to encrypt random access files. Even though it has all kinds of vulnerabilities, it's all well studied so the risk is measurable.

What is a somewhat secure way of generating a 64 bit signature?

I would like to sign a device, and I have 64 bits to store my signature in the device. This device has a MAC address and some other details (about 30 bytes worth) I can mangle to create my signature.
If possible, I would like the method to be one-way, so that I can verify that the signature is valid without knowing how to create a valid signature. Most public-private keys have this feature but they generate signatures that are 48 bytes long (I only have 8 bytes).
Implementation in Python is a plus.
Thanks
EDIT:
Thanks for the advice everyone. It sounds like there is no secure way to do this, only a way that is moderately inconvenient to attackers. I'll probably use a cryptographic hash combined with secret bit-shuffling. This will be as secure as any other link in my (very weak) 'security'.
Hash functions and digital signatures are very different things.
The size of a digital signature depends on the underlying hash function and the key length. So in theory, you can create an RSA implementation that generates 64-bit signatures, but that'd be an extremely weak signature.
For smaller key lengths, you might want to look at elliptic curve cryptography.
EDIT: Yes, I'm a cryptographer.
EDIT 2: Yet if you only need a hash function, you can look at elf64 or RIPEMD-64 as Fernando Miguélez suggested.
EDIT 3: Doing the math, you'd need to use 16-bit keys in ECC to generate 64-bit signatures, which is very weak. For ECC, anything less than 128 bits can be considered weak. For RSA this is 1024 bits.
Basically what you need is a 64-bit cryptographic hash funcion, such as Ripemd-64 or elf-64. Then you encrypt the hash with a cryptographic method and you got a 64 bit signature. The only problem is, from the point of view of a non-cryptoanalyst, that 64 bit offers a much weaker signature than typical over-128 bit hash. Nonetheless it could still be suitable for your application.
You could just use a standard hashing function (MD5 SHA1) and only use the first or last 30 bytes.
The number of bytes a hashing function generates is fairly arbitrary - it's obviously a trade off between space and uniqueness. There is nothing special about the lenght of the signature they use.
Edit - sorry I was thinking that MD5 returned 32bytes- it actaulyl returns 16bytes but is ussually written as 32hex digits.

Resources