I'm wondering how C_DecryptFinal & C_Decrypt are supposed to deal with padding errors.
According to pkcs11 2.20, C_DecryptFinal can return CKR_ENCRYPTED_DATA_INVALID or CKR_ENCRYPTED_DATA_LEN_RANGE,
so I suppose that if padding is invalid, C_DecryptFinal/C_Decrypt return CKR_ENCRYPTED_DATA_INVALID.
Is it correct?
If so, is C_DecryptFinal/C_Decrypt vulnerable to padding-oracle attacks?
Citing the standard (section 11.1.6):
CKR_ENCRYPTED_DATA_LEN_RANGE: The ciphertext input to a decryption
operation has been determined to be invalid ciphertext solely on the
basis of its length. Depending on the operation’s mechanism, this
could mean that the ciphertext is too short, too long, or is not a
multiple of some particular blocksize. This return value has higher
priority than CKR_ENCRYPTED_DATA_INVALID.
CKR_ENCRYPTED_DATA_INVALID: The encrypted input to a decryption
operation has been determined to be invalid ciphertext. This return
value has lower priority than CKR_ENCRYPTED_DATA_LEN_RANGE.
So for block ciphers the CKR_ENCRYPTED_DATA_LEN_RANGE should be returned when the input is not block-aligned.
If the input is block-aligned, the CKR_ENCRYPTED_DATA_INVALID is probably returned in case of wrong padding for the CKM_*_PAD mechanisms.
Thus the padding oracle attack is probably possible.
As the PKCS#7 padding is the only defined padding scheme for block ciphers, it is quite often the responsibility of the application to handle the padding, which leads to what I think should be the answer to your question:
It is up to the application (i.e. "the cryptoki client") not to provide an external attacker (i.e. the "the application client") with any oracle to determine the padding was wrong, regardless of the source of this information (i.e. the cryptoki or the application itself).
It is probably meaningless to protect against the padding oracle attack on the cryptoki interface level (i.e. an attacker inside the application), as such an attacker can decrypt anything at will directly using the appropriate functions.
(Of course it is better to use some form of authenticated encryption and do not need to worry about the padding oracle attack at all)
Desclaimer: I am no crypto expert, so please do validate my thoughts.
Related
Can hashes or keys generated (either intentionally or accidentally) that would trigger an injection attack? For example, if the hash or key was generated as something like SELECT%0d*%0dFROM%0dWHEREVER, could this cause an injection attack? I am aware with current technologies and standards, any decent protection will protect against all input, hashes and keys included, so it almost surely wouldn't effect any systems in reality.
Yes, I have been informed this is the wrong location for this type of question. Yes, I am now aware of where to put it next time.
In theory, I suppose it's possible that the result of a hash function would result in a specific sequence of bytes that happens to be SQL syntax, either when used as raw binary bytes or if encoded in the range of printable ASCII characters (values 0x20 through 0x7F).
But it would be a hard task to come up with an input string that produced that exact result when hashed.
The result of a hash function is always of fixed length, depending on the hash algorithm and options. So you would need to have an attack query in mind that fit in that fixed length exactly, and then you would need to find the input that hashed to that string exactly.
Also, the method for defending against such an attack is the same as defending against any other SQL injection attack: use query parameters. Any unsafe content, no matter if it is the result of a hash function or not, is able to effect an SQL injection if it is kept separate from the SQL syntax.
I think there are other means of attack that would be easier and more effective. Social hacking is still the most general-purpose means of attack, and can get around just about any security defense.
This should be a simple question, but I can't find any examples or figure out the answer from the openssl docs.
I want to encrypt exactly 128 bits, which should fit in one encryption block.
So I call EVP_EncyptInit_ex, and then what?
Do I call EVP_EncryptUpdate_ex (to encrypt the 128 bit block) and EVP_EncryptFinal_ex (even though there is nothing more left to encrypt)?
Or only EVP_EncryptUpdate_ex?
Or only EVP_EncryptFinal_ex?
Here, you have already figured out the steps.
So, it will be
EVP_encryptInit_ex
EVP_EncryptUpdate_ex
EVP_EncryptFinal_ex
EVP_EncryptFinal_ex also take care of the fact that data is not in multiple of block lengths.
In my opinion, if you have only to use AES with no padding (EVP_ interfaces takes care of padding), then go for AES_encrypt.
They are fairly easy to use.
//Step 1: Set encrypt key.
AES_KEY aeskey;
AES_set_encrypt_key(key, bits, &aeskey);
//Step2: Encrypt exactly 128 bits.
AES_encrypt(data, dataout, &aeskey);
AES encryption of 16 bytes without padding
Use the EVP_* interfaces and disable padding on the block.
Use the EVP_* interface because it supports engines and hardware acceleration, like AES-NI. The AES_encrypt functions are software based and do not support alternate implementations. Also, its not readily apparent, but AES_encrypt is not portable - some platforms suffer endianess issues.
You need to call EVP_CIPHER_CTX_set_padding to ensure no padding is added. From the EVP_CIPHER_CTX_set_padding(3) man page:
EVP_CIPHER_CTX_set_padding() enables or disables padding. By default
encryption operations are padded using standard block padding and the
padding is checked and removed when decrypting. If the pad parameter
is zero then no padding is performed, the total amount of data
encrypted or decrypted must then be a multiple of the block size or an
error will occur.
This function should be called after the context is set up for
encryption or decryption with EVP_EncryptInit_ex().
So your steps are:
Call EVP_CIPHER_CTX_new to create a context
Call EVP_EncryptInit_ex with the context
Call EVP_CIPHER_CTX_set_padding on the context
Call EVP_EncryptUpdate_ex to encrypt the data
Call EVP_EncryptFinal_ex to retrieve the cipher text
Also see EVP Symmetric Encryption and Decryption on the OpenSSL wiki.
I have some offline files that have to be password-protected. My strategy is as follows:
Cipher Algorithm: AES, 128-bit block, 256-bit key (PBKDF2-SHA-256
10000 iterations with a random salt stored plainly elsewhere)
Whole file is divided into pages with page size 1024 bytes
For a complete page, CBC is used
For an incomplete page,
Use CBC with cipher text stealing if it has at least one block
Use CTR if it has less one block
With this setup, we can keep the same file size
IV or nonce will be based on the salt and deterministic. Since this is not for network communication, I reckon we don't need to concern about replay attacks?
Question: Will this kind of mixing lower the security? Would we better off just use CTR throughout the whole file?
You're better off just using CTR for the entire file. Otherwise, you're adding a lot of extra work, in supporting multiple modes (CBC, CTR, and CTS) and determining which mode to use. It's not clear there's any value in doing so, since CTR is perfectly fine for encrypting a large amount of data.
Are you planning on reusing the same IV for each page? You should expand a bit on what you mean by a page, but I'd recommend unique IV's for each page. Are these pages addressable somehow? You might want to look into some of the new disk encryption modes for an idea on generating unique IV's
You also really need to MAC your data. In CTR for example, if someone flips a bit of the ciphertext, it'll flip the bit when you decrypt, and you'll never know it was tampered with. You can use HMAC or if you want to simplify your entire scheme, use AES GCM mode, which combines CTR for encryption and GMAC for integrity
There are a few things you need to know about CTR mode. After you know them all you could happily apply a stream cipher in your situation:
never ever reuse a data key with the same nonce;
above, not even in time;
be aware that CTR mode really shows the size of the encrypted data; always encrypting full blocks can hide this somewhat (in general a 1024 byte block takes as much as a single bit block if the file system boundaries are honored);
CTR mode in itself does not provide authentication (for completion, as this was already discussed);
If you don't keep to the first two rules, an attacker will immediately see the place of the edit and the attacker will be able to retrieve data directly related to the plain text.
On a possitive node:
you can happily use the offset (in, e.g., blocks) in the file to be part of the nonce;
it is very easy to seek in files, buffer ciphertext and create multi-threaded code around CTR.
And in general:
it pays off to use a data specific key specific sets of files, in such a way that if a key is compromised or changed that you don't have to re-encrypt everything;
think very well about how your keys are used, stored, backed up etc. Key management is the hardest part;
I currently perform penetration testing of ASP.NET application and trying to exploit Padding Oracle Attack. This AFAIK is based on response code analysis, but both ScriptResource and WebResource axds of the system under test always respond with 200 OK, even if cipher has been invalid. In this case, however, the content of the response is an empty string.
Is it possible to use any of the axd as the oracle in this case? Maybe basing on response content difference.
The Padding Oracle Attack works by being able to distinguish between two cases:
The server failed to decrypt the data because, upon decryption, it did not found a properly formatted padding.
The server found a correct padding, but the decrypted data turned out to be random junk.
There may be several ways for an attacker to get such a distinction. A specific error code from the server is just the easiest to exploit; but any detectable difference is enough. The attack was first published in 2002 (yes, it took 8 years for people to notice that it could be applied to ASP !) and it has been demonstrated on a SSL connection with only a timing difference: the server was decrypting the data, and then was verifying the MAC only if the decryption went fine; the extra 2ms taken by the MAC computation were enough for the attacker to know whether the padding was valid, allowing for direct application of the Padding Oracle Attack.
To answer your original question, the content length can be used. Padbuster notes the status code but I think it detects entirely off the response length.
To answer your reply to Troy, a long ciphertext length does not indicate they are vulnerable. Typically a short ciphertext length does indicate they are vulnerable, but you need to dot net url decode the value then see if modulus 8=0 to see if it's vulnerable. In other words, the length will be a multiple of 8. Usually i'll see one block of ciphertext (16 bytes) end up about 25 bytes once it's dot net url encoded. The fix includes a HMAC (I think), which extends the length and should make one block cipertexts impossible. I can't say this with certainty, as I'm not sure how long the HMAC is and if it works after padding or not.
It sounds to me like the padding oracle patch may have been installed and as a result you're not getting the error codes you were expecting. Have a look at Do you trust your hosting provider and have they really installed the padding oracle patch and see if you can establish this.
There are many articles and quotes on the web saying that a 'salt' must be kept secret. Even the Wikipedia entry on Salt:
For best security, the salt value is
kept secret, separate from the
password database. This provides an
advantage when a database is stolen,
but the salt is not. To determine a
password from a stolen hash, an
attacker cannot simply try common
passwords (such as English language
words or names). Rather, they must
calculate the hashes of random
characters (at least for the portion
of the input they know is the salt),
which is much slower.
Since I happen to know for a fact that encryption Salt (or Initialization Vectors) are OK to be stored on clear text along with the encrypted text, I want to ask why is this misconception perpetuated ?
My opinion is that the origin of the problem is a common confusion between the encryption salt (the block cipher's initialization vector) and the hashing 'salt'. In storing hashed passwords is a common practice to add a nonce, or a 'salt', and is (marginally) true that this 'salt' is better kept secret. Which in turn makes it not a salt at all, but a key, similar to the much clearly named secret in HMAC. If you look at the article Storing Passwords - done right! which is linked from the Wikipedia 'Salt' entry you'll see that is talking about this kind of 'salt', the password hash. I happen to disagree with most of these schemes because I believe that a password storage scheme should also allow for HTTP Digest authentication, in which case the only possible storage is the HA1 digest of the username:realm:password, see Storing password in tables and Digest authentication.
If you have an opinion on this issue, please post here as a response.
Do you think that the salt for block cipher encryption should be hidden? Explain why and how.
Do you agree that the blanket statement 'salts should be hidden' originates from salted hashing and does not apply to encryption?
Sould we include stream ciphers in discussion (RC4)?
If you are talking about IV in block cipher, it definitely should be in clear. Most people make their cipher weaker by using secret IV.
IV should be random, different for each encryption. It's very difficult to manage a random IV so some people simply use a fixed IV, defeating the purpose of IV.
I used to work with a database with password encrypted using secret fixed IV. The same password is always encrypted to the same ciphertext. This is very prone to rainbow table attack.
Do you think that the salt for block
cipher encryption should be hidden?
Explain why and how
No it shouldn't. The strength of a block cipher relies on the key. IMO you should not increase the strength of your encryption by adding extra secrets. If the cipher and key are not strong enough then you need to change the cipher or key length, not start keeping other bits of data secret. Security is hard enough so keep it simple.
Like LFSR Consulting says:
There are people that are much smarter
than you and I that have spent more
time thinking about this topic than
you or I ever will.
Which is a loaded answer to say the least. There are folks who, marginally in the honest category, will overlook some restraints when money is available. There are a plethora of people who have no skin at the fire and will lower the boundaries for that type,....
then, not too far away, there is a type of risk that comes from social factors - which is almost impossible to program away. For that person, setting up a device solely to "break the locks" can be an exercise of pure pleasure for no gain or measurable reason. That said, you asked that those who have an opinion please respond so here goes:
Do you think that the salt for block
cipher encryption should be hidden?
Explain why and how.
Think of it this way, it adds to the computational strength needed. It's just one more thing to hide if it has to be hidden. By and of it's self, being forced to hide ( salt, iv, or anything ) places the entity doing the security in the position of being forced to do something. Anytime the opposition can tell you what to do, they can manipulate you. If it leaks, that should have been caught by cross-controls that would have detected the leak and replacement salts available. There is no perfect cipher, save otp, and even that can be compromised somehow as greatest risk comes from within.
In my opinion, the only solution is to be selective about whom you do any security for - the issue of protecting salts leads to issues that are relevant to the threat model. Obviously, keys have to be protected. If you have to protect the salt, you probably need to review your burger flippin resume and question the overall security approach of those for whom you are working.
There is no answer, actually.
Do you agree that the blanket statement 'salts should be hidden' originates from salted hashing and does not apply to encryption?
Who said this, where, and what basis was given.
Should we include stream ciphers in discussion (RC4)?
A cipher is a cipher - what difference would it make?
Each encrypted block is the next block IV. So by definition, the IV cannot be secret. Each block is an IV.
The first block is not very different. An attacker who knows the length of the plain text could have a hint that the first block is the IV.
BLOCK1 could be IV or Encrypted with well known IV
BLOCK2 is encrypted with BLOCK#1 as an IV
...
BLOCK N is encrypted with BLOCK#N-1 as an IV
Still, whenever possible, I generate a random (non-null) IV and give it to each party out-of-band. But the security gain is probably not that important.
The purpose of a per record salt is to make the task of reversing the hashes much harder. So if a password database is exposed the effort required to break the passwords is increased. So assuming that the attacker knows exactly how you perform the hash, rather than constructing a single rainbow table for the entire database they need to do this for every entry in the database.
The per record salt is usually some combination of fields in the record that vary greatly between records. Transaction time, Account Number, transaction Number are all good examples of fields that can be used in a per record salt. A record salt should come from other fields in the record. So yes it is not secret, but you should avoid publicising the method of calculation.
There is a separate issue with a database wide salt. This is a sort of key, and protects against the attacker using existing rainbow tables to crack the passwords. The database wide salt should be stored separately so that if the database is compromised then it is unlikely that the attacker will get this value as well.
A database wide salt should be treated as though it was a key and access to the salt value should be moderately protected. One way of doing this is to split the salt into components that are managed in different domains. One component in the code, one in a configuration file, one in the database. Only the running code should be able to read all of these and combine them together using a bit wide XOR.
The last area is where many fail. There must be a way to change these salt values and or algorithm. If a security incident occurs we may want to be able to change the salt values easily. The database should have a salt version field and the code will use the version to identify which salts to use and in what combination. The encryption or hash creation always uses the latest salt algorithm, but the decode verify function always uses the algorithm specified in the record. This way a low priority thread can read through the database decrypting and re-encrypting the entries.