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);
}
_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);
try
{
- written = ProcessFinalBlock(input, rented);
+ written = CipherUpdate(input, rented);
rented.AsSpan(0, written).CopyTo(output);
}
finally
}
else
{
- written = ProcessFinalBlock(input, output);
+ written = CipherUpdate(input, output);
}
return written;
};
}
- 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
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)
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.