mirror of https://github.com/dotnet/runtime
Merge c28d62976a
into 02596ba8d9
This commit is contained in:
commit
91e623adef
|
@ -258,6 +258,9 @@ internal static partial class Interop
|
|||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes128Ccm")]
|
||||
internal static partial IntPtr EvpAes128Ccm();
|
||||
|
||||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes128WrapPad")]
|
||||
internal static partial IntPtr EvpAes128WrapPad();
|
||||
|
||||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes192Ecb")]
|
||||
internal static partial IntPtr EvpAes192Ecb();
|
||||
|
||||
|
@ -276,6 +279,9 @@ internal static partial class Interop
|
|||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes192Ccm")]
|
||||
internal static partial IntPtr EvpAes192Ccm();
|
||||
|
||||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes192WrapPad")]
|
||||
internal static partial IntPtr EvpAes192WrapPad();
|
||||
|
||||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes256Ecb")]
|
||||
internal static partial IntPtr EvpAes256Ecb();
|
||||
|
||||
|
@ -294,6 +300,9 @@ internal static partial class Interop
|
|||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes256Ccm")]
|
||||
internal static partial IntPtr EvpAes256Ccm();
|
||||
|
||||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpAes256WrapPad")]
|
||||
internal static partial IntPtr EvpAes256WrapPad();
|
||||
|
||||
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDesCbc")]
|
||||
internal static partial IntPtr EvpDesCbc();
|
||||
|
||||
|
|
|
@ -1237,7 +1237,7 @@
|
|||
Link="Common\System\Security\Cryptography\SlhDsaImplementation.NotSupported.cs" />
|
||||
<Compile Include="$(CommonPath)System\Security\Cryptography\SP800108HmacCounterKdfImplementationManaged.cs"
|
||||
Link="Common\System\Security\Cryptography\SP800108HmacCounterKdfImplementationManaged.cs" />
|
||||
<Compile Include="System\Security\Cryptography\AesImplementation.OpenSsl.cs" />
|
||||
<Compile Include="System\Security\Cryptography\AesImplementation.Android.cs" />
|
||||
<Compile Include="System\Security\Cryptography\AesCcm.Android.cs" />
|
||||
<Compile Include="System\Security\Cryptography\AesGcm.Android.cs" />
|
||||
<Compile Include="System\Security\Cryptography\AsnFormatter.Managed.cs" />
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
namespace System.Security.Cryptography
|
||||
{
|
||||
internal sealed partial class AesImplementation
|
||||
{
|
||||
private static UniversalCryptoTransform CreateTransformCore(
|
||||
CipherMode cipherMode,
|
||||
PaddingMode paddingMode,
|
||||
ReadOnlySpan<byte> key,
|
||||
byte[]? iv,
|
||||
int blockSize,
|
||||
int paddingSize,
|
||||
int feedback,
|
||||
bool encrypting)
|
||||
{
|
||||
// The algorithm pointer is a static pointer, so not having any cleanup code is correct.
|
||||
IntPtr algorithm = GetAlgorithm(key.Length * 8, feedback * 8, cipherMode);
|
||||
|
||||
BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, paddingSize, key, iv, encrypting);
|
||||
return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting);
|
||||
}
|
||||
|
||||
private static OpenSslCipherLite CreateLiteCipher(
|
||||
CipherMode cipherMode,
|
||||
ReadOnlySpan<byte> key,
|
||||
ReadOnlySpan<byte> iv,
|
||||
int blockSize,
|
||||
int paddingSize,
|
||||
int feedback,
|
||||
bool encrypting)
|
||||
{
|
||||
IntPtr algorithm = GetAlgorithm(key.Length * 8, feedback * 8, cipherMode);
|
||||
return new OpenSslCipherLite(algorithm, blockSize, paddingSize, key, iv, encrypting);
|
||||
}
|
||||
|
||||
private static IntPtr GetAlgorithm(int keySize, int feedback, CipherMode cipherMode) =>
|
||||
(keySize, cipherMode) switch
|
||||
{
|
||||
// Neither OpenSSL nor Cng Aes support CTS mode.
|
||||
|
||||
(128, CipherMode.CBC) => Interop.Crypto.EvpAes128Cbc(),
|
||||
(128, CipherMode.ECB) => Interop.Crypto.EvpAes128Ecb(),
|
||||
(128, CipherMode.CFB) when feedback == 8 => Interop.Crypto.EvpAes128Cfb8(),
|
||||
(128, CipherMode.CFB) when feedback == 128 => Interop.Crypto.EvpAes128Cfb128(),
|
||||
|
||||
(192, CipherMode.CBC) => Interop.Crypto.EvpAes192Cbc(),
|
||||
(192, CipherMode.ECB) => Interop.Crypto.EvpAes192Ecb(),
|
||||
(192, CipherMode.CFB) when feedback == 8 => Interop.Crypto.EvpAes192Cfb8(),
|
||||
(192, CipherMode.CFB) when feedback == 128 => Interop.Crypto.EvpAes192Cfb128(),
|
||||
|
||||
(256, CipherMode.CBC) => Interop.Crypto.EvpAes256Cbc(),
|
||||
(256, CipherMode.ECB) => Interop.Crypto.EvpAes256Ecb(),
|
||||
(256, CipherMode.CFB) when feedback == 8 => Interop.Crypto.EvpAes256Cfb8(),
|
||||
(256, CipherMode.CFB) when feedback == 128 => Interop.Crypto.EvpAes256Cfb128(),
|
||||
|
||||
_ => throw (keySize == 128 || keySize == 192 || keySize == 256 ? (Exception)
|
||||
new NotSupportedException() :
|
||||
new CryptographicException(SR.Cryptography_InvalidKeySize)),
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace System.Security.Cryptography
|
||||
{
|
||||
internal sealed partial class AesImplementation
|
||||
|
@ -35,6 +39,75 @@ namespace System.Security.Cryptography
|
|||
return new OpenSslCipherLite(algorithm, blockSize, paddingSize, key, iv, encrypting);
|
||||
}
|
||||
|
||||
protected override void EncryptKeyWrapPaddedCore(ReadOnlySpan<byte> source, Span<byte> destination)
|
||||
{
|
||||
int written = KeyWrap(source, destination, enc: 1);
|
||||
Debug.Assert(written == destination.Length);
|
||||
}
|
||||
|
||||
protected override int DecryptKeyWrapPaddedCore(ReadOnlySpan<byte> source, Span<byte> destination)
|
||||
{
|
||||
return KeyWrap(source, destination, enc: 0);
|
||||
}
|
||||
|
||||
private int KeyWrap(ReadOnlySpan<byte> source, Span<byte> destination, int enc)
|
||||
{
|
||||
Debug.Assert(enc is 0 or 1);
|
||||
|
||||
SafeEvpCipherCtxHandle ctx = GetKey().UseKey(
|
||||
state: enc,
|
||||
static (enc, key) =>
|
||||
{
|
||||
int keySizeInBits = key.Length * 8;
|
||||
|
||||
IntPtr algorithm = GetKeyWrapAlgorithm(keySizeInBits);
|
||||
|
||||
SafeEvpCipherCtxHandle ctx = Interop.Crypto.EvpCipherCreate(
|
||||
algorithm,
|
||||
ref MemoryMarshal.GetReference(key),
|
||||
key.Length * 8,
|
||||
ref MemoryMarshal.GetReference(ReadOnlySpan<byte>.Empty),
|
||||
enc);
|
||||
|
||||
if (ctx.IsInvalid)
|
||||
{
|
||||
ctx.Dispose();
|
||||
throw Interop.Crypto.CreateOpenSslCryptographicException();
|
||||
}
|
||||
|
||||
return ctx;
|
||||
});
|
||||
|
||||
int written;
|
||||
|
||||
using (ctx)
|
||||
{
|
||||
bool ret = Interop.Crypto.EvpCipherUpdate(
|
||||
ctx,
|
||||
destination,
|
||||
out written,
|
||||
source);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
throw Interop.Crypto.CreateOpenSslCryptographicException();
|
||||
}
|
||||
|
||||
Debug.Assert(written > 0);
|
||||
|
||||
// Experimentation and code insepection show that EVP_CipherFinal_ex is not needed here,
|
||||
// the work is done in EVP_CipherUpdate.
|
||||
// Since AES-KW(P) involves multiple passes over the data, where the end of each pass
|
||||
// stores a tag/checksum back in the beginning of the buffer, it makes sense that only
|
||||
// one of Update or Final could write data, and they chose to go with Update.
|
||||
//
|
||||
// As the call to Final does not yield more data, and we're about to dispose the context,
|
||||
// don't bother making the call.
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
private static IntPtr GetAlgorithm(int keySize, int feedback, CipherMode cipherMode) =>
|
||||
(keySize, cipherMode) switch
|
||||
{
|
||||
|
@ -59,5 +132,14 @@ namespace System.Security.Cryptography
|
|||
new NotSupportedException() :
|
||||
new CryptographicException(SR.Cryptography_InvalidKeySize)),
|
||||
};
|
||||
|
||||
private static IntPtr GetKeyWrapAlgorithm(int keySize) =>
|
||||
keySize switch
|
||||
{
|
||||
128 => Interop.Crypto.EvpAes128WrapPad(),
|
||||
192 => Interop.Crypto.EvpAes192WrapPad(),
|
||||
256 => Interop.Crypto.EvpAes256WrapPad(),
|
||||
_ => throw new CryptographicException(SR.Cryptography_InvalidKeySize),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,18 +100,21 @@ static const Entry s_cryptoNative[] =
|
|||
DllImportEntry(CryptoNative_EvpAes128Cfb8)
|
||||
DllImportEntry(CryptoNative_EvpAes128Ecb)
|
||||
DllImportEntry(CryptoNative_EvpAes128Gcm)
|
||||
DllImportEntry(CryptoNative_EvpAes128WrapPad)
|
||||
DllImportEntry(CryptoNative_EvpAes192Cbc)
|
||||
DllImportEntry(CryptoNative_EvpAes192Ccm)
|
||||
DllImportEntry(CryptoNative_EvpAes192Cfb128)
|
||||
DllImportEntry(CryptoNative_EvpAes192Cfb8)
|
||||
DllImportEntry(CryptoNative_EvpAes192Ecb)
|
||||
DllImportEntry(CryptoNative_EvpAes192Gcm)
|
||||
DllImportEntry(CryptoNative_EvpAes192WrapPad)
|
||||
DllImportEntry(CryptoNative_EvpAes256Cbc)
|
||||
DllImportEntry(CryptoNative_EvpAes256Ccm)
|
||||
DllImportEntry(CryptoNative_EvpAes256Cfb128)
|
||||
DllImportEntry(CryptoNative_EvpAes256Cfb8)
|
||||
DllImportEntry(CryptoNative_EvpAes256Ecb)
|
||||
DllImportEntry(CryptoNative_EvpAes256Gcm)
|
||||
DllImportEntry(CryptoNative_EvpAes256WrapPad)
|
||||
DllImportEntry(CryptoNative_EvpChaCha20Poly1305)
|
||||
DllImportEntry(CryptoNative_EvpCipherCreate2)
|
||||
DllImportEntry(CryptoNative_EvpCipherCreatePartial)
|
||||
|
|
|
@ -453,18 +453,21 @@ extern bool g_libSslUses32BitTime;
|
|||
REQUIRED_FUNCTION(EVP_aes_128_cfb8) \
|
||||
REQUIRED_FUNCTION(EVP_aes_128_ecb) \
|
||||
REQUIRED_FUNCTION(EVP_aes_128_gcm) \
|
||||
REQUIRED_FUNCTION(EVP_aes_128_wrap_pad) \
|
||||
REQUIRED_FUNCTION(EVP_aes_192_cbc) \
|
||||
REQUIRED_FUNCTION(EVP_aes_192_ccm) \
|
||||
REQUIRED_FUNCTION(EVP_aes_192_cfb128) \
|
||||
REQUIRED_FUNCTION(EVP_aes_192_cfb8) \
|
||||
REQUIRED_FUNCTION(EVP_aes_192_ecb) \
|
||||
REQUIRED_FUNCTION(EVP_aes_192_gcm) \
|
||||
REQUIRED_FUNCTION(EVP_aes_192_wrap_pad) \
|
||||
REQUIRED_FUNCTION(EVP_aes_256_cbc) \
|
||||
REQUIRED_FUNCTION(EVP_aes_256_ccm) \
|
||||
REQUIRED_FUNCTION(EVP_aes_256_cfb128) \
|
||||
REQUIRED_FUNCTION(EVP_aes_256_cfb8) \
|
||||
REQUIRED_FUNCTION(EVP_aes_256_ecb) \
|
||||
REQUIRED_FUNCTION(EVP_aes_256_gcm) \
|
||||
REQUIRED_FUNCTION(EVP_aes_256_wrap_pad) \
|
||||
LIGHTUP_FUNCTION(EVP_chacha20_poly1305) \
|
||||
LEGACY_FUNCTION(EVP_CIPHER_CTX_cleanup) \
|
||||
REQUIRED_FUNCTION(EVP_CIPHER_CTX_ctrl) \
|
||||
|
@ -472,6 +475,7 @@ extern bool g_libSslUses32BitTime;
|
|||
LEGACY_FUNCTION(EVP_CIPHER_CTX_init) \
|
||||
FALLBACK_FUNCTION(EVP_CIPHER_CTX_new) \
|
||||
FALLBACK_FUNCTION(EVP_CIPHER_CTX_reset) \
|
||||
REQUIRED_FUNCTION(EVP_CIPHER_CTX_set_flags) \
|
||||
REQUIRED_FUNCTION(EVP_CIPHER_CTX_set_key_length) \
|
||||
REQUIRED_FUNCTION(EVP_CIPHER_CTX_set_padding) \
|
||||
RENAMED_FUNCTION(EVP_CIPHER_get_nid, EVP_CIPHER_nid) \
|
||||
|
@ -1025,18 +1029,21 @@ extern TYPEOF(OPENSSL_gmtime)* OPENSSL_gmtime_ptr;
|
|||
#define EVP_aes_128_ecb EVP_aes_128_ecb_ptr
|
||||
#define EVP_aes_128_gcm EVP_aes_128_gcm_ptr
|
||||
#define EVP_aes_128_ccm EVP_aes_128_ccm_ptr
|
||||
#define EVP_aes_128_wrap_pad EVP_aes_128_wrap_pad_ptr
|
||||
#define EVP_aes_192_cbc EVP_aes_192_cbc_ptr
|
||||
#define EVP_aes_192_cfb8 EVP_aes_192_cfb8_ptr
|
||||
#define EVP_aes_192_cfb128 EVP_aes_192_cfb128_ptr
|
||||
#define EVP_aes_192_ecb EVP_aes_192_ecb_ptr
|
||||
#define EVP_aes_192_gcm EVP_aes_192_gcm_ptr
|
||||
#define EVP_aes_192_ccm EVP_aes_192_ccm_ptr
|
||||
#define EVP_aes_192_wrap_pad EVP_aes_192_wrap_pad_ptr
|
||||
#define EVP_aes_256_cbc EVP_aes_256_cbc_ptr
|
||||
#define EVP_aes_256_cfb8 EVP_aes_256_cfb8_ptr
|
||||
#define EVP_aes_256_cfb128 EVP_aes_256_cfb128_ptr
|
||||
#define EVP_aes_256_ecb EVP_aes_256_ecb_ptr
|
||||
#define EVP_aes_256_gcm EVP_aes_256_gcm_ptr
|
||||
#define EVP_aes_256_ccm EVP_aes_256_ccm_ptr
|
||||
#define EVP_aes_256_wrap_pad EVP_aes_256_wrap_pad_ptr
|
||||
#define EVP_chacha20_poly1305 EVP_chacha20_poly1305_ptr
|
||||
#define EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup_ptr
|
||||
#define EVP_CIPHER_CTX_ctrl EVP_CIPHER_CTX_ctrl_ptr
|
||||
|
@ -1044,6 +1051,7 @@ extern TYPEOF(OPENSSL_gmtime)* OPENSSL_gmtime_ptr;
|
|||
#define EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init_ptr
|
||||
#define EVP_CIPHER_CTX_new EVP_CIPHER_CTX_new_ptr
|
||||
#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_reset_ptr
|
||||
#define EVP_CIPHER_CTX_set_flags EVP_CIPHER_CTX_set_flags_ptr
|
||||
#define EVP_CIPHER_CTX_set_key_length EVP_CIPHER_CTX_set_key_length_ptr
|
||||
#define EVP_CIPHER_CTX_set_padding EVP_CIPHER_CTX_set_padding_ptr
|
||||
#define EVP_CIPHER_get_nid EVP_CIPHER_get_nid_ptr
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#define SUCCESS 1
|
||||
#define KEEP_CURRENT_DIRECTION -1
|
||||
|
||||
c_static_assert(EVP_CIPHER_CTX_FLAG_WRAP_ALLOW == 1);
|
||||
|
||||
EVP_CIPHER_CTX*
|
||||
CryptoNative_EvpCipherCreate2(const EVP_CIPHER* type, uint8_t* key, int32_t keyLength, unsigned char* iv, int32_t enc)
|
||||
{
|
||||
|
@ -30,6 +32,9 @@ CryptoNative_EvpCipherCreate2(const EVP_CIPHER* type, uint8_t* key, int32_t keyL
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Required for OpenSSL 1.1 AES-KWP, no-op in OpenSSL 3.
|
||||
EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
|
||||
|
||||
// Perform partial initialization so we can set the key lengths
|
||||
int ret = EVP_CipherInit_ex(ctx, type, NULL, NULL, NULL, 0);
|
||||
if (!ret)
|
||||
|
@ -275,6 +280,12 @@ const EVP_CIPHER* CryptoNative_EvpAes128Ccm(void)
|
|||
return EVP_aes_128_ccm();
|
||||
}
|
||||
|
||||
const EVP_CIPHER* CryptoNative_EvpAes128WrapPad(void)
|
||||
{
|
||||
// No error queue impact.
|
||||
return EVP_aes_128_wrap_pad();
|
||||
}
|
||||
|
||||
const EVP_CIPHER* CryptoNative_EvpAes192Ecb(void)
|
||||
{
|
||||
// No error queue impact.
|
||||
|
@ -311,6 +322,12 @@ const EVP_CIPHER* CryptoNative_EvpAes192Ccm(void)
|
|||
return EVP_aes_192_ccm();
|
||||
}
|
||||
|
||||
const EVP_CIPHER* CryptoNative_EvpAes192WrapPad(void)
|
||||
{
|
||||
// No error queue impact.
|
||||
return EVP_aes_192_wrap_pad();
|
||||
}
|
||||
|
||||
const EVP_CIPHER* CryptoNative_EvpAes256Ecb(void)
|
||||
{
|
||||
// No error queue impact.
|
||||
|
@ -347,6 +364,12 @@ const EVP_CIPHER* CryptoNative_EvpAes256Ccm(void)
|
|||
return EVP_aes_256_ccm();
|
||||
}
|
||||
|
||||
const EVP_CIPHER* CryptoNative_EvpAes256WrapPad(void)
|
||||
{
|
||||
// No error queue impact.
|
||||
return EVP_aes_256_wrap_pad();
|
||||
}
|
||||
|
||||
const EVP_CIPHER* CryptoNative_EvpDesEcb(void)
|
||||
{
|
||||
// No error queue impact.
|
||||
|
|
|
@ -158,6 +158,14 @@ Direct shim to EVP_aes_128_ccm.
|
|||
*/
|
||||
PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes128Ccm(void);
|
||||
|
||||
/*
|
||||
Function:
|
||||
EvpAes128WrapPad
|
||||
|
||||
Direct shim to EVP_aes_128_wrap_pad.
|
||||
*/
|
||||
PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes128WrapPad(void);
|
||||
|
||||
/*
|
||||
Function:
|
||||
EvpAes192Ecb
|
||||
|
@ -206,6 +214,14 @@ Direct shim to EVP_aes_192_ccm.
|
|||
*/
|
||||
PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes192Ccm(void);
|
||||
|
||||
/*
|
||||
Function:
|
||||
EvpAes192WrapPad
|
||||
|
||||
Direct shim to EVP_aes_192_wrap_pad.
|
||||
*/
|
||||
PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes192WrapPad(void);
|
||||
|
||||
/*
|
||||
Function:
|
||||
EvpAes256Ecb
|
||||
|
@ -254,6 +270,14 @@ Direct shim to EVP_aes_256_ccm.
|
|||
*/
|
||||
PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes256Ccm(void);
|
||||
|
||||
/*
|
||||
Function:
|
||||
EvpAes256WrapPad
|
||||
|
||||
Direct shim to EVP_aes_256_wrap_pad.
|
||||
*/
|
||||
PALEXPORT const EVP_CIPHER* CryptoNative_EvpAes256WrapPad(void);
|
||||
|
||||
/*
|
||||
Function:
|
||||
EvpDes3Ecb
|
||||
|
|
Loading…
Reference in New Issue