[System.Security.SecurityCritical] // auto-generated
internal static byte[] RsaOaepDecrypt (RSA rsa, HashAlgorithm hash, PKCS1MaskGenerationMethod mgf, byte[] encryptedData) {
int cb = rsa.KeySize / 8;
// 1. Decode the input data
// It is important that the Integer to Octet String conversion errors be indistinguishable from the other decoding
// errors to protect against chosen cipher text attacks
// A lecture given by James Manger during Crypto 2001 explains the issue in details
byte[] data = null;
try {
data = rsa.DecryptValue(encryptedData);
}
catch (CryptographicException) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
}
// 2. Create the hash object so we can get its size info.
int cbHash = hash.HashSize / 8;
// 3. Let maskedSeed be the first hLen octects and maskedDB
// be the remaining bytes.
int zeros = cb - data.Length;
if (zeros < 0 || zeros >= cbHash)
throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
byte[] seed = new byte[cbHash];
Buffer.InternalBlockCopy(data, 0, seed, zeros, seed.Length - zeros);
byte[] DB = new byte[data.Length - seed.Length + zeros];
Buffer.InternalBlockCopy(data, seed.Length - zeros, DB, 0, DB.Length);
// 4. seedMask = MGF(maskedDB, hLen);
byte[] mask = mgf.GenerateMask(DB, seed.Length);
// 5. seed = seedMask XOR maskedSeed
int i = 0;
for (i=0; i < seed.Length; i++) {
seed[i] ^= mask[i];
}
// 6. dbMask = MGF(seed, |EM| - hLen);
mask = mgf.GenerateMask(seed, DB.Length);
// 7. DB = maskedDB xor dbMask
for (i=0; i < DB.Length; i++) {
DB[i] = (byte) (DB[i] ^ mask[i]);
}
// 8. pHash = HASH(P)
hash.ComputeHash(EmptyArray<Byte>.Value);
// 9. DB = pHash' || PS || 01 || M
// 10. Check that pHash = pHash'
byte[] hashValue = hash.Hash;
for (i=0; i < cbHash; i++) {
if (DB[i] != hashValue[i])
throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
}
// Check that PS is all zeros
for (; i<DB.Length; i++) {
if (DB[i] == 1)
break;
else if (DB[i] != 0)
throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
}
if (i == DB.Length)
throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
i++; // skip over the one
// 11. Output M.
byte[] output = new byte[DB.Length - i];
Buffer.InternalBlockCopy(DB, i, output, 0, output.Length);
return output;
}