public virtual byte[] Decrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> ciphertext, ReadOnlySpan <byte> associatedData = default) { if (ciphertext.Length + nonce.Length < _snuffle.NonceSizeInBytes + Poly1305.MAC_TAG_SIZE_IN_BYTES) { throw new ArgumentException($"The {nameof(ciphertext)} is too short."); } if (nonce.IsEmpty || nonce.Length != _snuffle.NonceSizeInBytes) { throw new ArgumentException(_snuffle.FormatNonceLengthExceptionMessage(_snuffle.GetType().Name, nonce.Length, _snuffle.NonceSizeInBytes)); } var limit = ciphertext.Length - Poly1305.MAC_TAG_SIZE_IN_BYTES; try { Poly1305.VerifyMac(GetMacKey(nonce), GetMacDataRfc8439(associatedData, ciphertext.Slice(0, limit)), ciphertext.Slice(limit, Poly1305.MAC_TAG_SIZE_IN_BYTES)); } catch (Exception ex) { throw new CryptographicException(AEAD_EXCEPTION_INVALID_TAG, ex); } return(_snuffle.Decrypt(ciphertext.Slice(0, limit), nonce)); }
/// <summary> /// Decrypts the <paramref name="ciphertext"/> into the <paramref name="plaintext"/> provided destination buffer if the authentication <paramref name="tag"/> can be validated. /// </summary> /// <param name="nonce">The nonce associated with this message, which must match the value provided during encryption.</param> /// <param name="ciphertext">The encrypted content to decrypt.</param> /// <param name="tag">The authentication tag produced for this message during encryption.</param> /// <param name="plaintext">The byte span to receive the decrypted contents.</param> /// <param name="associatedData">Extra data associated with this message, which must match the value provided during encryption.</param> /// <exception cref="CryptographicException">The tag value could not be verified, or the decryption operation otherwise failed.</exception> public void Decrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> ciphertext, ReadOnlySpan <byte> tag, Span <byte> plaintext, ReadOnlySpan <byte> associatedData = default) { if (nonce.IsEmpty || nonce.Length != _snuffle.NonceSizeInBytes) { throw new ArgumentException(Snuffle.FormatNonceLengthExceptionMessage(_snuffle.GetType().Name, nonce.Length, _snuffle.NonceSizeInBytes)); } try { var aadPaddedLen = GetPaddedLength(associatedData, Poly1305.MAC_TAG_SIZE_IN_BYTES); var ciphertextPaddedLen = GetPaddedLength(ciphertext, Poly1305.MAC_TAG_SIZE_IN_BYTES); var macData = new Span <byte>(new byte[aadPaddedLen + ciphertextPaddedLen + Poly1305.MAC_TAG_SIZE_IN_BYTES]); PrepareMacDataRfc8439(macData, associatedData, aadPaddedLen, ciphertext, ciphertextPaddedLen); Poly1305.VerifyMac(GetMacKey(nonce), macData, tag); } catch (CryptographicException ex) when(ex.Message.Contains("length")) { throw; } catch (Exception ex) { throw new CryptographicException(AEAD_EXCEPTION_INVALID_TAG, ex); } _snuffle.Decrypt(ciphertext, nonce, plaintext); }
public void VerifyMacWhenTagLengthIsEmptyFails() { // Arrange, Act & Assert Action act = () => Poly1305.VerifyMac(new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES], new byte[0], new byte[0]); act.Should().Throw <CryptographicException>().WithMessage(EXCEPTION_MESSAGE_TAG_LENGTH); }
public void VerifyMacWhenTagLengthIsInvalidFails() { // Arrange, Act & Assert Action act = () => Poly1305.VerifyMac(new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES], new byte[0], new byte[Poly1305.MAC_TAG_SIZE_IN_BYTES + TestHelpers.ReturnRandomPositiveNegative()]); act.Should().Throw <CryptographicException>().WithMessage(EXCEPTION_MESSAGE_TAG_LENGTH); }
public void VerifyMacWhenKeyLengthIsLessThan32Fails() { // Arrange, Act & Assert Action act = () => Poly1305.VerifyMac(new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES - 1], new byte[0], new byte[0]); act.Should().Throw <CryptographicException>(); }
public void VerifyMacFails() { // Arrange var key = new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES]; key[0] = 1; // Act & Assert Assert.Throws <CryptographicException>(() => Poly1305.VerifyMac(key, new byte[] { 1 }, new byte[Poly1305.MAC_TAG_SIZE_IN_BYTES])); }
/// <summary> /// Decrypts the <paramref name="ciphertext"> into the <paramref name="plaintext"> provided destination buffer if the authentication <paramref name="tag"> can be validated. /// </summary> /// <param name="nonce">The nonce associated with this message, which must match the value provided during encryption.</param> /// <param name="ciphertext">The encrypted content to decrypt.</param> /// <param name="tag">The authentication tag produced for this message during encryption.</param> /// <param name="plaintext">The byte span to receive the decrypted contents.</param> /// <param name="associatedData">Extra data associated with this message, which must match the value provided during encryption.</param> /// <exception cref="CryptographicException">The tag value could not be verified, or the decryption operation otherwise failed.</exception> public virtual void Decrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> ciphertext, ReadOnlySpan <byte> tag, Span <byte> plaintext, ReadOnlySpan <byte> associatedData = default) { if (nonce.IsEmpty || nonce.Length != _snuffle.NonceSizeInBytes) { throw new ArgumentException(_snuffle.FormatNonceLengthExceptionMessage(_snuffle.GetType().Name, nonce.Length, _snuffle.NonceSizeInBytes)); } try { Poly1305.VerifyMac(GetMacKey(nonce), GetMacDataRfc8439(associatedData, ciphertext), tag); } catch (Exception ex) { throw new CryptographicException(AEAD_EXCEPTION_INVALID_TAG, ex); } _snuffle.Decrypt(ciphertext, nonce, plaintext); }
public void RandomMacTest() { var rnd = new Random(); for (var i = 0; i < 1000; i++) { // Arrange var data = new byte[rnd.Next(300)]; rnd.NextBytes(data); var key = new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES]; rnd.NextBytes(key); // Act var mac = Poly1305.ComputeMac(key, data); // Assert Assert.DoesNotThrow(() => Poly1305.VerifyMac(key, data, mac)); } }
public void RandomMacOldMethodSignatureTest() { var rnd = new Random(); for (var i = 0; i < 1000; i++) { // Arrange var key = new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES]; RandomNumberGenerator.Fill(key); var data = new byte[rnd.Next(300)]; rnd.NextBytes(data); // Act var mac = Poly1305.ComputeMac(key, data); // Assert Action act = () => Poly1305.VerifyMac(key, data, mac); act.Should().NotThrow(); } }
public void VerifyMacWhenKeyLengthIsGreaterThan32Fails() { // Arrange, Act & Assert Assert.Throws <CryptographicException>(() => Poly1305.VerifyMac(new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES + 1], new byte[0], new byte[0])); }