/
AesCcm.cs
101 lines (84 loc) · 3.53 KB
/
AesCcm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.Versioning;
using Internal.Cryptography;
namespace System.Security.Cryptography
{
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
public sealed partial class AesCcm : IDisposable
{
public static KeySizes NonceByteSizes { get; } = new KeySizes(7, 13, 1);
public static KeySizes TagByteSizes { get; } = new KeySizes(4, 16, 2);
public AesCcm(ReadOnlySpan<byte> key)
{
ThrowIfNotSupported();
AesAEAD.CheckKeySize(key.Length);
ImportKey(key);
}
public AesCcm(byte[] key)
{
ThrowIfNotSupported();
ArgumentNullException.ThrowIfNull(key);
AesAEAD.CheckKeySize(key.Length);
ImportKey(key);
}
public void Encrypt(byte[] nonce, byte[] plaintext, byte[] ciphertext, byte[] tag, byte[]? associatedData = null)
{
ArgumentNullException.ThrowIfNull(nonce);
ArgumentNullException.ThrowIfNull(plaintext);
ArgumentNullException.ThrowIfNull(ciphertext);
ArgumentNullException.ThrowIfNull(tag);
Encrypt((ReadOnlySpan<byte>)nonce, plaintext, ciphertext, tag, associatedData);
}
public void Encrypt(
ReadOnlySpan<byte> nonce,
ReadOnlySpan<byte> plaintext,
Span<byte> ciphertext,
Span<byte> tag,
ReadOnlySpan<byte> associatedData = default)
{
CheckParameters(plaintext, ciphertext, nonce, tag);
EncryptCore(nonce, plaintext, ciphertext, tag, associatedData);
}
public void Decrypt(byte[] nonce, byte[] ciphertext, byte[] tag, byte[] plaintext, byte[]? associatedData = null)
{
ArgumentNullException.ThrowIfNull(nonce);
ArgumentNullException.ThrowIfNull(ciphertext);
ArgumentNullException.ThrowIfNull(tag);
ArgumentNullException.ThrowIfNull(plaintext);
Decrypt((ReadOnlySpan<byte>)nonce, ciphertext, tag, plaintext, associatedData);
}
public void Decrypt(
ReadOnlySpan<byte> nonce,
ReadOnlySpan<byte> ciphertext,
ReadOnlySpan<byte> tag,
Span<byte> plaintext,
ReadOnlySpan<byte> associatedData = default)
{
CheckParameters(plaintext, ciphertext, nonce, tag);
DecryptCore(nonce, ciphertext, tag, plaintext, associatedData);
}
private static void CheckParameters(
ReadOnlySpan<byte> plaintext,
ReadOnlySpan<byte> ciphertext,
ReadOnlySpan<byte> nonce,
ReadOnlySpan<byte> tag)
{
if (plaintext.Length != ciphertext.Length)
throw new ArgumentException(SR.Cryptography_PlaintextCiphertextLengthMismatch);
if (!nonce.Length.IsLegalSize(NonceByteSizes))
throw new ArgumentException(SR.Cryptography_InvalidNonceLength, nameof(nonce));
if (!tag.Length.IsLegalSize(TagByteSizes))
throw new ArgumentException(SR.Cryptography_InvalidTagLength, nameof(tag));
}
private static void ThrowIfNotSupported()
{
if (!IsSupported)
{
throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(AesCcm)));
}
}
}
}