From 75a40ae10ef9a943e46391a7d7d3cdb6d6137dfc Mon Sep 17 00:00:00 2001 From: Dennis Dyall Date: Thu, 28 Nov 2024 00:30:16 +0100 Subject: [PATCH] misc: edits to StoreDataCommand and ChannelEncryption ChannelEncyrption: use Span instead of byte[] StoreDataCommand: change order of fields --- .../YubiKey/Scp/Commands/StoreDataCommand.cs | 3 +- .../YubiKey/Scp/Helpers/ChannelEncryption.cs | 37 +++++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Commands/StoreDataCommand.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Commands/StoreDataCommand.cs index 2b53c626..acc236d1 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Commands/StoreDataCommand.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Commands/StoreDataCommand.cs @@ -28,11 +28,10 @@ namespace Yubico.YubiKey.Scp.Commands /// internal class StoreDataCommand : IYubiKeyCommand { + public YubiKeyApplication Application => YubiKeyApplication.SecurityDomain; private const byte GpStoreDataIns = 0xE2; private readonly ReadOnlyMemory _data; - public YubiKeyApplication Application => YubiKeyApplication.SecurityDomain; - /// /// Initializes a new instance of the class, with the given data to be stored. /// diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Helpers/ChannelEncryption.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Helpers/ChannelEncryption.cs index 23fd8486..671ccb84 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Helpers/ChannelEncryption.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Scp/Helpers/ChannelEncryption.cs @@ -23,7 +23,7 @@ internal static class ChannelEncryption /// /// Encrypts the provided data using AES CBC mode with the given key and encryption counter. /// - /// The data to be encrypted. + /// The data to be encrypted. /// The AES key to use for encryption. /// /// A counter used to generate the initialization vector (IV) for encryption. @@ -32,20 +32,23 @@ internal static class ChannelEncryption /// A containing the encrypted data. /// public static ReadOnlyMemory EncryptData( - ReadOnlySpan dataToEncrypt, + ReadOnlySpan plainText, ReadOnlySpan encryptionKey, int encryptionCounter) { - // NB: Could skip this if the payload is empty (rather than sending a 16-byte encrypted '0x800000...' payload - byte[] countBytes = new byte[sizeof(int)]; + Span countBytes = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32BigEndian(countBytes, encryptionCounter); - byte[] ivInput = new byte[16]; - countBytes.CopyTo(ivInput, 16 - countBytes.Length); // copy to rightmost part of block - var iv = AesUtilities.BlockCipher(encryptionKey, ivInput); + Span ivInput = stackalloc byte[16]; + int offset = 16 - countBytes.Length; + countBytes.CopyTo(ivInput[offset..]); - var paddedPayload = Padding.PadToBlockSize(dataToEncrypt); - var encryptedData = AesUtilities.AesCbcEncrypt(encryptionKey, iv.Span, paddedPayload.Span); + var iv = AesUtilities.BlockCipher(encryptionKey, ivInput); + var paddedPlaintext = Padding.PadToBlockSize(plainText); + var encryptedData = AesUtilities.AesCbcEncrypt( + encryptionKey, + iv.Span, + paddedPlaintext.Span); return encryptedData; } @@ -53,7 +56,7 @@ public static ReadOnlyMemory EncryptData( /// /// Decrypts the provided data using AES CBC mode with the given key and encryption counter. /// - /// The encrypted data to be decrypted. + /// The encrypted data to be decrypted. /// The AES key to use for decryption. /// /// A counter used to generate the initialization vector (IV) for decryption. @@ -62,21 +65,23 @@ public static ReadOnlyMemory EncryptData( /// A containing the decrypted data with padding removed. /// public static ReadOnlyMemory DecryptData( - ReadOnlySpan dataToDecrypt, + ReadOnlySpan encryptedData, ReadOnlySpan key, int encryptionCounter) { - byte[] countBytes = new byte[sizeof(int)]; + Span countBytes = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32BigEndian(countBytes, encryptionCounter); - byte[] ivInput = new byte[16]; - countBytes.CopyTo(ivInput, 16 - countBytes.Length); // copy to rightmost part of block + Span ivInput = stackalloc byte[16]; + int offset = 16 - countBytes.Length; ivInput[0] = 0x80; // to mark as RMAC calculation + countBytes.CopyTo(ivInput[offset..]); var iv = AesUtilities.BlockCipher(key, ivInput); - var decryptedData = AesUtilities.AesCbcDecrypt(key, iv.Span, dataToDecrypt); + var decryptedData = AesUtilities.AesCbcDecrypt(key, iv.Span, encryptedData); - return Padding.RemovePadding(decryptedData.Span); + var plainText = Padding.RemovePadding(decryptedData.Span); + return plainText; } } }