Skip to content

Commit 50e6f07

Browse files
authored
Pass IV through cipher resets for OpenSSL and Android
1 parent c99b3c7 commit 50e6f07

File tree

9 files changed

+41
-38
lines changed

9 files changed

+41
-38
lines changed

src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,15 @@ internal static void CipherSetNonceLength(SafeEvpCipherCtxHandle ctx, int nonceL
6464

6565
[GeneratedDllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_CipherReset")]
6666
[return: MarshalAs(UnmanagedType.Bool)]
67-
internal static partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx);
67+
private static unsafe partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, byte* pIv, int cIv);
68+
69+
internal static unsafe bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, ReadOnlySpan<byte> iv)
70+
{
71+
fixed (byte* pIv = &MemoryMarshal.GetReference(iv))
72+
{
73+
return EvpCipherReset(ctx, pIv, iv.Length);
74+
}
75+
}
6876

6977
[GeneratedDllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_CipherCtxSetPadding")]
7078
[return: MarshalAs(UnmanagedType.Bool)]

src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,15 @@ internal static void EvpCipherSetCcmNonceLength(SafeEvpCipherCtxHandle ctx, int
7676

7777
[GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpCipherReset")]
7878
[return: MarshalAs(UnmanagedType.Bool)]
79-
internal static partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx);
79+
private static unsafe partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, byte* pIv, int cIv);
80+
81+
internal static unsafe bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, ReadOnlySpan<byte> iv)
82+
{
83+
fixed (byte* pIv = &MemoryMarshal.GetReference(iv))
84+
{
85+
return EvpCipherReset(ctx, pIv, iv.Length);
86+
}
87+
}
8088

8189
[GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpCipherCtxSetPadding")]
8290
[return: MarshalAs(UnmanagedType.Bool)]

src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSslCipherLite.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public unsafe int Transform(ReadOnlySpan<byte> input, Span<byte> output)
125125

126126
public void Reset(ReadOnlySpan<byte> iv)
127127
{
128-
bool status = Interop.Crypto.EvpCipherReset(_ctx);
128+
bool status = Interop.Crypto.EvpCipherReset(_ctx, iv);
129129
CheckBoolReturn(status);
130130

131131
#if DEBUG

src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ int32_t AndroidCryptoNative_CipherCtxSetPadding(CipherCtx* ctx, int32_t padding)
316316
}
317317
}
318318

319-
int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx)
319+
int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx, uint8_t* pIv, int32_t cIv)
320320
{
321321
if (!ctx)
322322
return FAIL;
@@ -334,6 +334,20 @@ int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx)
334334
if (CheckJNIExceptions(env))
335335
return FAIL;
336336

337+
if (pIv)
338+
{
339+
if (ctx->ivLength != cIv)
340+
{
341+
return FAIL;
342+
}
343+
344+
SaveTo(pIv, &ctx->iv, (size_t)ctx->ivLength, /* overwrite */ true);
345+
}
346+
else if (cIv != 0)
347+
{
348+
return FAIL;
349+
}
350+
337351
return ReinitializeCipher(ctx);
338352
}
339353

src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ PALEXPORT int32_t AndroidCryptoNative_CipherSetTagLength(CipherCtx* ctx, int32_t
3131
PALEXPORT int32_t AndroidCryptoNative_CipherSetKeyAndIV(CipherCtx* ctx, uint8_t* key, uint8_t* iv, int32_t enc);
3232
PALEXPORT int32_t AndroidCryptoNative_CipherSetNonceLength(CipherCtx* ctx, int32_t ivLength);
3333
PALEXPORT void AndroidCryptoNative_CipherDestroy(CipherCtx* ctx);
34-
PALEXPORT int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx);
34+
PALEXPORT int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx, uint8_t* pIv, int32_t cIv);
3535
PALEXPORT int32_t AndroidCryptoNative_CipherCtxSetPadding(CipherCtx* ctx, int32_t padding);
3636
PALEXPORT int32_t AndroidCryptoNative_CipherUpdateAAD(CipherCtx* ctx, uint8_t* in, int32_t inl);
3737
PALEXPORT int32_t AndroidCryptoNative_CipherUpdate(CipherCtx* ctx, uint8_t* out, int32_t* outl, uint8_t* in, int32_t inl);

src/native/libs/System.Security.Cryptography.Native/opensslshim.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
298298
LEGACY_FUNCTION(EVP_CIPHER_CTX_cleanup) \
299299
REQUIRED_FUNCTION(EVP_CIPHER_CTX_ctrl) \
300300
FALLBACK_FUNCTION(EVP_CIPHER_CTX_free) \
301-
LIGHTUP_FUNCTION(EVP_CIPHER_CTX_get_original_iv) \
302301
LEGACY_FUNCTION(EVP_CIPHER_CTX_init) \
303302
FALLBACK_FUNCTION(EVP_CIPHER_CTX_new) \
304303
FALLBACK_FUNCTION(EVP_CIPHER_CTX_reset) \
@@ -757,7 +756,6 @@ FOR_ALL_OPENSSL_FUNCTIONS
757756
#define EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup_ptr
758757
#define EVP_CIPHER_CTX_ctrl EVP_CIPHER_CTX_ctrl_ptr
759758
#define EVP_CIPHER_CTX_free EVP_CIPHER_CTX_free_ptr
760-
#define EVP_CIPHER_CTX_get_original_iv EVP_CIPHER_CTX_get_original_iv_ptr
761759
#define EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init_ptr
762760
#define EVP_CIPHER_CTX_new EVP_CIPHER_CTX_new_ptr
763761
#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_reset_ptr

src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ typedef struct ossl_lib_ctx_st OSSL_LIB_CTX;
1818
void ERR_new(void);
1919
void ERR_set_debug(const char *file, int line, const char *func);
2020
void ERR_set_error(int lib, int reason, const char *fmt, ...);
21-
int EVP_CIPHER_CTX_get_original_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len);
2221
int EVP_CIPHER_get_nid(const EVP_CIPHER *e);
2322
int EVP_MD_get_size(const EVP_MD* md);
2423
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits);

src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.c

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -123,36 +123,12 @@ void CryptoNative_EvpCipherDestroy(EVP_CIPHER_CTX* ctx)
123123
}
124124
}
125125

126-
int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx)
127-
{
128-
// EVP_CipherInit_ex with all nulls preserves the algorithm, resets the IV,
129-
// and maintains the key.
130-
//
131-
// The only thing that you can't do is change the encryption direction,
132-
// that requires passing the key and IV in again.
133-
//
134-
// But since we have a different object returned for CreateEncryptor
135-
// and CreateDecryptor we don't need to worry about that.
136-
uint8_t* iv = NULL;
137-
138-
#ifdef NEED_OPENSSL_3_0
139-
// OpenSSL 3.0 alpha 13 does not properly reset the IV. Work around that by
140-
// asking for the original IV, and giving it back.
141-
uint8_t tmpIV[EVP_MAX_IV_LENGTH];
142-
143-
// If we're direct against 3.0, or we're portable and found 3.0
144-
if (API_EXISTS(EVP_CIPHER_CTX_get_original_iv))
145-
{
146-
if (EVP_CIPHER_CTX_get_original_iv(ctx, tmpIV, sizeof(tmpIV)) != 1)
147-
{
148-
return 0;
149-
}
150-
151-
iv = tmpIV;
152-
}
153-
#endif
126+
int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx, uint8_t* pIv, int32_t cIv)
127+
{
128+
assert(cIv >= 0 && (pIv != NULL || cIv == 0));
129+
(void)cIv;
154130

155-
return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, KEEP_CURRENT_DIRECTION);
131+
return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, pIv, KEEP_CURRENT_DIRECTION);
156132
}
157133

158134
int32_t CryptoNative_EvpCipherCtxSetPadding(EVP_CIPHER_CTX* x, int32_t padding)

src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ EvpCipherReset
3535
3636
Resets an EVP_CIPHER_CTX instance for a new computation.
3737
*/
38-
PALEXPORT int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx);
38+
PALEXPORT int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx, uint8_t* pIv, int32_t cIv);
3939

4040
/*
4141
Function:

0 commit comments

Comments
 (0)