Omit calls to CCCryptorFinal
authorKevin Jones <kevin@vcsjones.com>
Sun, 12 Jun 2022 21:34:12 +0000 (17:34 -0400)
committerGitHub <noreply@github.com>
Sun, 12 Jun 2022 21:34:12 +0000 (17:34 -0400)
src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs
src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AppleCCCryptorLite.cs
src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c
src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.c
src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.h

index 3ba3936..2cda7d2 100644 (file)
@@ -68,14 +68,6 @@ internal static partial class Interop
             out int cbWritten,
             out int ccStatus);
 
-        [LibraryImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_CryptorFinal")]
-        internal static unsafe partial int CryptorFinal(
-            SafeAppleCryptorHandle cryptor,
-            byte* pbOutput,
-            int cbOutput,
-            out int cbWritten,
-            out int ccStatus);
-
         [LibraryImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_CryptorReset")]
         internal static unsafe partial int CryptorReset(SafeAppleCryptorHandle cryptor, byte* pbIv, out int ccStatus);
     }
index 779af66..c4ea205 100644 (file)
@@ -75,6 +75,21 @@ namespace System.Security.Cryptography
             _isFinalized = true;
 #endif
 
+            // We just use CCCryptorUpdate instead of CCCryptorFinal. From the
+            // Apple documentation:
+
+            // In the following cases, the CCCryptorFinal() is superfluous as
+            // it will not yield any data nor return an error:
+            //     1. Encrypting or decrypting with a block cipher with padding
+            //        disabled, when the total amount of data provided to
+            //        CCCryptorUpdate() is an integral multiple of the block size.
+            //     2. Encrypting or decrypting with a stream cipher.
+
+            // For case 1, we do all of our padding manually and the cipher is opened with
+            // PAL_PaddingMode.None. So that condition is met. For the second part, we always
+            // submit data as a multiple of the block size, and is asserted below. So this condition
+            // is met.
+
             Debug.Assert((input.Length % PaddingSizeInBytes) == 0);
             Debug.Assert(input.Length <= output.Length);
 
@@ -86,7 +101,7 @@ namespace System.Security.Cryptography
 
                 try
                 {
-                    written = ProcessFinalBlock(input, rented);
+                    written = CipherUpdate(input, rented);
                     rented.AsSpan(0, written).CopyTo(output);
                 }
                 finally
@@ -96,7 +111,7 @@ namespace System.Security.Cryptography
             }
             else
             {
-                written = ProcessFinalBlock(input, output);
+                written = CipherUpdate(input, output);
             }
 
             return written;
@@ -183,39 +198,6 @@ namespace System.Security.Cryptography
             };
         }
 
-        private unsafe int ProcessFinalBlock(ReadOnlySpan<byte> input, Span<byte> output)
-        {
-            if (input.Length == 0)
-            {
-                return 0;
-            }
-
-            int outputBytes = CipherUpdate(input, output);
-            int ret;
-            int errorCode;
-
-            Debug.Assert(output.Length > 0);
-
-            fixed (byte* outputStart = output)
-            {
-                byte* outputCurrent = outputStart + outputBytes;
-                int bytesWritten;
-
-                ret = Interop.AppleCrypto.CryptorFinal(
-                    _cryptor,
-                    outputCurrent,
-                    output.Length - outputBytes,
-                    out bytesWritten,
-                    out errorCode);
-
-                outputBytes += bytesWritten;
-            }
-
-            ProcessInteropError(ret, errorCode);
-
-            return outputBytes;
-        }
-
         private static void ProcessInteropError(int functionReturnCode, int ccStatus)
         {
             // Success
index 5bd8d16..16e1efe 100644 (file)
@@ -96,7 +96,6 @@ static const Entry s_cryptoAppleNative[] =
     DllImportEntry(AppleCryptoNative_CryptorFree)
     DllImportEntry(AppleCryptoNative_CryptorCreate)
     DllImportEntry(AppleCryptoNative_CryptorUpdate)
-    DllImportEntry(AppleCryptoNative_CryptorFinal)
     DllImportEntry(AppleCryptoNative_CryptorReset)
     DllImportEntry(AppleCryptoNative_StoreEnumerateUserRoot)
     DllImportEntry(AppleCryptoNative_StoreEnumerateMachineRoot)
index 3bf5646..b395a86 100644 (file)
@@ -108,27 +108,6 @@ int32_t AppleCryptoNative_CryptorUpdate(CCCryptorRef cryptor,
     return status == kCCSuccess;
 }
 
-int32_t AppleCryptoNative_CryptorFinal(
-    CCCryptorRef cryptor, uint8_t* pbOutput, int32_t cbOutput, int32_t* pcbWritten, int32_t* pccStatus)
-{
-    if (pccStatus == NULL)
-        return -1;
-
-    *pccStatus = 0;
-
-    if (pbOutput == NULL || cbOutput < 0 || pcbWritten == NULL)
-        return -1;
-
-    size_t sizeWritten = 0;
-    CCStatus status =
-        CCCryptorFinal(cryptor, pbOutput, (size_t)cbOutput, &sizeWritten);
-
-    // Safe because sizeWritten is bounded by cbOutput.
-    *pcbWritten = SizeTToInt32(sizeWritten);
-    *pccStatus = status;
-    return status == kCCSuccess;
-}
-
 int32_t AppleCryptoNative_CryptorReset(CCCryptorRef cryptor, const uint8_t* pbIv, int32_t* pccStatus)
 {
     if (pccStatus == NULL)
index 0238635..5dcaee2 100644 (file)
@@ -92,14 +92,6 @@ PALEXPORT int32_t AppleCryptoNative_CryptorUpdate(CCCryptorRef cryptor,
                                                   int32_t* pkCCStatus);
 
 /*
-Shims CCCryptorFinal, updating *pkCCStatus as its output.
-
-Returns 1 on success, 0 on system error, -1 on input error.
-*/
-PALEXPORT int32_t AppleCryptoNative_CryptorFinal(
-    CCCryptorRef cryptor, uint8_t* pbOutput, int32_t cbOutput, int32_t* pcbWritten, int32_t* pkCCStatus);
-
-/*
 Shims CCCryptorReset, updating *pkCCStatus as its output.
 
 Returns 1 on success, 0 on system error, -1 on input error.