I use a TPM 2.0 with verified and measured boot. Now I read about external TPM modules for mainboards, which do not have a TPM module yet. I am a bit confused on how secure this is.
I think a attack vector could look like this:
Put a man-in-the-middle device between mainboard and TPM which records every data sent
This way an attacker could exfiltrate e.g. windows bitlocker keys.
Are there any methods to prevent such attacks?
I am also interested about the security about TPM modules on motherboards, since there the same attack could be done.
How is the firmware measured into the TPM? Does this rely on data from the TPM?
Yes such man-in-the-middle attacks against the TPM are well-known; articles describing them seem to come out with regularity, almost on an annual basis (see here for the latest one).
The way to protect against them is session-based encryption. (see section 21 here)
To present the simplest use case, where the session is not an authorization session and is not bound to a TPM object: basically, you would start a salted session, which will ensure that only you and the TPM have access to the salt. Interception of the session start message would not help, as the salt is encrypted with a TPM key.
Then the session key is computed:
sessionKey ≔ KDFa(sessionAlg, salt, “ATH”, nonceTPM, nonceCaller, bits)
Note that the TPM is going to have to decrypt the salt on its end.
The XOR mask for encrypting the message is computed thusly for each exchange:
mask ≔ KDFa (hashAlg, sessionKey, “XOR”, nonce1, nonce2, data.size • 8)
The protected data is then encrypted by XORing it with the computed mask for parameter encryption. Note that the mask is going to be different for each encryption operation, as the nonces are constantly refreshed.
There is also an option to use CFB mode encryption on devices that support it.
Related
TL;DR
Do I have to sign every single message, or is there a more efficient way of verifying the origin of messages?
I am developing a simple crypto protocol for fun. Of course I know that in any serious project, I should just use some industry standard, like OpenSSL, but this is for learning and experimenting.
The idea is that the communicating terminals exchange RSA public keys, then using these keys they exchange an AES key securely, so that the AES key can be used to encrypt every message from this point. I have already implemented all of this, and it works fine.
The problem is: a potential attacker cannot read anything thanks to AES, but could still for example cause errors or attempt to hijack the communication or do some other nasty stuff by being man-in-the-middle (for instance she/he could copy an encrypted message and disrupt things by sending it again and again). What I need is digital signature so I can confirm that messages are coming from the valid source and I'm in luck, because I already have a working RSA implementation.
I know how digital signatures work (taking the hash of the message and encrypting it using the private key, etc.), but the only way I can think of making this work is to sign every single message, then check whether the signature is valid or not on the receiving side. However, I'm concerned that this will slow down my protocol. The whole purpose of using AES to secure the communication (or any symmetric key encryption) is that it's a lot faster than RSA (or any public key encryption). Wouldn't doing this defeat the purpose of AES (or any symmetric key encryption)? So the question is: do I have to sign every single message? Or is there a more efficient way of doing this? How does for example OpenSSL handle this?
TL;DR Use authenticated encryption.
In symmetric encryption it is possible to produce a Message Authentication Code (MAC) that enables you to check whether a message that you sent was (maliciously) manipulated. A man-in-the-middle attacker has only a negligible advantage of forging an authentication tag for a message that you haven't tagged.
There are many ways of doing this, but it's generally seen that a MAC should authenticate the ciphertext and not the plaintext (Should we MAC-then-encrypt or encrypt-then-MAC?). Popular MAC algorithms are HMAC (e.g. HMAC-SHA256), CMAC/OMAC1 or GMAC. There are also some distinct authenticated modes such as GCM, EAX, OCB, SIV, CWC, etc. Those combine a mode to achieve confidentiality and a mode for authenticity without the need of different keys for both.
But this is not enough because this only enables the receiver to detect tampering or forgeries of messages. An attacker may still mount other attacks such as replay or delay attacks. Therefore you need to send nonces (such as a message counter) and time stamps along. The receiver would have to keep a record of previously sent messages (by storing the nonces) and not accept any messages that are sent too late judging by its internal clock.
In order to prevent the attacker from changing the nonces and time stamps at will, those also have to be authenticated. Most authenticated modes are actually Authenticated Encryption with Associated Data which can authenticate additional non-secret data such as nonces and time stamps.
The use of authenticated encryption can make a purely symmetric communication relatively tamper-proof under the assumption that the key was exchanged confidentially and was also verified through conventional digital-signatures such as RSA-PSS or Ed25519 (EdDSA).
If I do an authentication to a DESFire card using AES, do I need to do the key diversification? If so, is there some code example of how to do the diversification?
No, you don't have to use a diversified key. You can just as well use the same key(s) for all your DESFire cards. However, it is advisable to use a diversified key in order to prevent attacks on the whole system if an attacker discovers the key(s) for one card.
With regard to key diversification functions, I suggest that you take a look at NXP's application note on Symmetric key diversifications.
On my fingerprint scanner, the fingerprints are stored in the device itself. I'm sure that this is the same as most of them.
How do the scanners protect/encrypt the fingerprint data, so that someone can't extract this information directly from the scanner and use it to authenticate? I know that this would require serious skill, but I'm sure that I'm not the only one who has thought of the possibility.
Fingerprint devices typically do not encrypt or store your fingerprint data. What usually happens is as follows:
the scan of your fingertip is analysed for certain control points
the position of these generates a token
this token is used similarly to a password hash and is passed to the authentication app
communication with the app may be encrypted with a key which is time specific, to avoid replay attacks
Which is similar to how a password hash is stored , as per #Wiso's answer, in a shadow password file, or in a SAM file under Windows.
So if you are looking at controls, the key elements are the algorithm the device uses to generate the token, the comms between the device and the application, and the storage used by the application.
I don't think your device encrypt your fingerprint data. Suppose it does, where will your device store the key to decrypt it? Usually from system password systems create an hash from the password using a salt, look at shadow password.
I was arguing about an S3 like aproach using authorization hash with a secret key as the seed and some data on the request as the message signed with hmac sha1 (Amazon S3 way) vs an other developer supporting symetric encryption of the data with a secret key known by the emiter and the server.
What are the advantage of using signed data with hmac sha1 vs symetric key other than the fact that with the former, we do not need to encrypt the username or password.
What would be the hardest to break ? symetric encryption or sha1 hashing at la S3 ?
If all big players are using oauth and similar without symetric key it is sure that there are obvious advantages, what are those ?
An hmac and a symmetric cipher are not mutually exclusive ideas. In fact AES-CMAC which is both an MAC (not hashed) and a symmetric cipher, AES-CMAC is the cryptographic primitive that makes WPA secure. (Although a WPA can still be broken using a rainbow table).
You should not need an exotic authentication system for this. Logging in with a username and password and maintaining session state with a cookie is commonly used because it is easy to implement and it is secure. By storing state, like a cookie its no longer technically RESTful, but there is nothing stopping you from doing it.
However, in terms of authentication I believe that asymmetric cryptography like RSA is the most secure. (Amazon uses asymmetric cryptography for ssh connections by default.) This allows you to only store the public keys, so that if your server where to be compromised no authentication credentials could be used. It also defends against MITM attacks. In many cases this can be implanted quite easily with REST because HTTPS already supports client certificates. You can sign the clients certificates for free and then verify them your self.
If implemented properly, the strength of an hmac vs symmetric cipher it mostly comes down to the strength of the secret. If you are using a secret like a password, then both systems are equally very weak. These secretes must be large, Cryptographically Secure Psudorandom Numbers. Another thing to keep in mind is that symmetric ciphers are very difficult to implement properly. Most programmers do not understand this and end up reusing PRNG when using stream cipher or when using a block cipher they use an incorrect mode and leave the IV null. By contrast HMACS are very easy to implement and less can go wrong. If everything is transmitted over HTTPS, and your are using an hmac then its easy to implement a secure authentication system. If you really want to implement a symmetric cipher you must get a copy of Piratical Cryptography, there are a few chapters devoted to symmetric ciphers alone because so much can go horribly wrong. You also have to take key distribution into consideration, ssl uses a DH-Key Exchange for its symmetric keys.
Make sure to read the OWASP top 10, especially Broken Authentication and Session Management. This requires the use of https for the entire session, most web application programmers don't realize this.
The big differences would be that HMAC would provide integrity but no privacy, while encryption would provide privacy without integrity. Many use cases would require both, but I can't think of any where integrity is unnecessary. HMAC seems like a minimum requirement, with encryption being a likely companion.
I'm not a cryptography expert, I actually only have a little bit of experience using it at all. Anyways, the time has come where one of my applications demands that I have some encryption set up. Please note, the program won't be managing anything super critical that will be able to cause a lot of damage.
Anyways, I was just trying to see if this scheme that I'm using is common and if there are flaws (of which there may be completely stupid & horribly flawed design, that's why I'm asking).
Ok, I have a client -> server communication. The Client I can hard code in the public portion of a 2048-bit RSA key. When the client wants to initiate a secure connection, he sends his username, md5 hash of his password, and a hash of a random UUID, all of which has been encrypted against the server's Public Key. The server receives the information and decrypts using its private key. Checks the database to see if his login + pass work & if they do, create a new entry in the "Sessions" table in the DB. This includes a SessionID, UID (user ID), and the UUID hash. Using the corresponding session ID's UUID as the keyphrase, the server will then send back a message that has the Blowfish encrypted word "Success!" + a random UUID (this message is Digitally Signed so we can determine if it came from the server or not). From that point on, when the client sends info to the server, it will be with a plaintext sess_id & include a Blowfish encrypted message, using the corresponding Session ID's blowfish secret (stored encrypted in the DB) as the key to encrypt / decrypt.
Specifically, I am curious as to whether this system "should work" or if anyone notices that it's glaringly obvious that a vulnerability exists, such as MITM.
Issues I can see off the top of my head (although you have left out most of the details, which is where the devil famously resides):
If you're using a UUID generator rather than a real cryptographic RNG, it likely has insufficient entropy. Don't discount this - in the real world, the favourite way of covertly weakening an encryption system has been to weaken the RNG;
Your initial RSA encryption sounds like it is susceptible to a small-exponent attack, and potentially other creative attacks. There's too much structure there to be comfortable;
It sounds like there's numerous opportunities for replay attacks;
What block cipher mode are you using with Blowfish?
I recommend using TLS/SSL - it's had a lot more friendly eyes looking at it for a lot longer than anything you build yourself ever will.
Just use SSL or DTLS, IKEv2, HIP, EAP or some suitable standard protocol. Don't try to invent your own crypto protocols, nobody has enough expertise to do this on their own. Your protocol doesn't have nearly enough entropy in it, so far as I can see, so your resulting keys will be pretty weak.
From that point on, when the client sends info to the server, it will be with a plaintext sess_id & include a Blowfish encrypted message, using the corresponding Session ID as the key to encrypt / decrypt.
If you're sending the session id in plaintext, and using it as the encryption key, how is that secure?
I see no reason why you can't use standard SSL authentication and let the library implementer worry about the handshaking.