2using System.Globalization;
4using System.Threading.Tasks;
15 public abstract class PaceProtocol() :
SecurityObject, IPaceProtocol
17 private System.Numerics.BigInteger version;
18 private System.Numerics.BigInteger? parameterId;
19 private bool configured;
24 public abstract Grade SecurityStrength {
get; }
29 public virtual bool ChipAuthenticationMapping =>
false;
34 public System.Numerics.BigInteger Version => this.version;
39 public System.Numerics.BigInteger? ParameterId => this.parameterId;
44 public abstract int Bits {
get; }
51 public override Grade Supports(
string Object)
53 return Object == this.Oid ? this.SecurityStrength :
Grade.NotAtAll;
59 public override bool IsConfigured => this.configured;
66 public override bool Configure(Vector SecurityInfo)
68 if (SecurityInfo.Length < 2)
71 if (SecurityInfo[1] is not
System.Numerics.BigInteger Version)
74 this.version = Version;
76 if (SecurityInfo.Length > 3)
78 else if (SecurityInfo.Length == 2)
80 this.configured =
true;
83 else if (SecurityInfo[2] is not
System.Numerics.BigInteger ParameterId)
87 this.parameterId = ParameterId;
88 this.configured =
true;
99 public abstract byte[] CreateNewKey(
byte[]? Seed, ref
int Index);
105 public abstract byte[] ImportKey(XmlDocument Xml);
111 public abstract IPaceProtocol CreateEphemeralKey();
119 public virtual byte[] GetSharedSecret(
byte[] RemotePublicKey)
122 throw new NotImplementedException(
"This protocol does not implement ephemeral key generation.");
130 public virtual Task<bool> Authenticate(TravelDocumentsClient Client)
132 return Task.FromResult(
false);
141 return TravelDocumentsClient.KDF(TravelDocumentsClient.PACE_K(Info), 3,
142 this.AdjustParity,
this.KdfHashFunction,
this.KdfHashKeyLength);
149 public byte[] KDF_Enc(
byte[] KSeed)
151 return TravelDocumentsClient.KDF(KSeed, 1, this.AdjustParity, this.KdfHashFunction, this.KdfHashKeyLength);
158 public byte[] KDF_Mac(
byte[] KSeed)
160 return TravelDocumentsClient.KDF(KSeed, 2, this.AdjustParity, this.KdfHashFunction, this.KdfHashKeyLength);
166 public virtual bool AdjustParity =>
false;
176 public virtual int KdfHashKeyLength => 16;
181 public virtual int BlockLength => 16;
192 byte[] Kπ = this.KDFπ(Info);
193 return this.DecryptNonce(Kπ, EncryptedNonce);
202 public virtual byte[] DecryptNonce(
byte[] Kπ,
byte[] EncryptedNonce)
204 return this.DecryptAes(Kπ, zeroIv16, EncryptedNonce);
213 public static byte[] CreateAssociatedData(
string Oid,
byte[] PublicKey)
215 string[] OidParts = Oid.Split(
'.');
216 int i, c = OidParts.Length;
217 byte[] OidBytes =
new byte[c];
219 for (i = 0; i < c; i++)
220 OidBytes[i] =
byte.Parse(OidParts[i], CultureInfo.InvariantCulture);
222 int d = PublicKey.Length;
223 byte[] AssociatedData =
new byte[7 + c + d];
225 AssociatedData[0] = 0x7f;
226 AssociatedData[1] = 0x49;
227 AssociatedData[2] = (byte)(4 + c + d);
228 AssociatedData[3] = 0x06;
229 AssociatedData[4] = (byte)(c - 1);
231 Buffer.BlockCopy(OidBytes, 1, AssociatedData, 5, c - 1);
234 AssociatedData[i++] = 0x86;
235 AssociatedData[i++] = (byte)(1 + d);
236 AssociatedData[i++] = 0x04;
238 Buffer.BlockCopy(PublicKey, 0, AssociatedData, i, d);
240 return AssociatedData;
248 public abstract CMac GetAuthenticator(
byte[] Key);
257 public virtual byte[] Encrypt(
byte[] Key,
byte[] IV,
byte[] Data)
259 return this.EncryptAes(Key, IV, Data);
269 public virtual byte[] Decrypt(
byte[] Key,
byte[] IV,
byte[] Data)
271 return this.DecryptAes(Key, IV, Data);
280 protected byte[] EncryptAes(
byte[] Key,
byte[] IV,
byte[] Data)
282 using Aes Cipher = Aes.Create();
283 Cipher.Mode = CipherMode.CBC;
284 Cipher.Padding = PaddingMode.None;
285 Cipher.BlockSize = this.BlockLength << 3;
286 Cipher.KeySize = Key.Length << 3;
288 using ICryptoTransform Encryptor = Cipher.CreateEncryptor(Key, IV);
290 return Encryptor.TransformFinalBlock(Data, 0, Data.Length);
300 protected byte[] Encrypt3Des(
byte[] Key,
byte[] IV,
byte[] Data)
302 using TripleDES Cipher = TripleDES.Create();
303 Cipher.Mode = CipherMode.CBC;
304 Cipher.Padding = PaddingMode.None;
306 using ICryptoTransform Encryptor = Cipher.CreateEncryptor(Key, IV);
308 return Encryptor.TransformFinalBlock(Data, 0, Data.Length);
318 protected byte[] DecryptAes(
byte[] Key,
byte[] IV,
byte[] EncryptedData)
320 using Aes Cipher = Aes.Create();
321 Cipher.Mode = CipherMode.CBC;
322 Cipher.Padding = PaddingMode.None;
323 Cipher.BlockSize = this.BlockLength << 3;
324 Cipher.KeySize = Key.Length << 3;
326 using ICryptoTransform Decryptor = Cipher.CreateDecryptor(Key, IV);
328 return Decryptor.TransformFinalBlock(EncryptedData, 0, EncryptedData.Length);
338 protected byte[] Decrypt3Des(
byte[] Key,
byte[] IV,
byte[] EncryptedData)
340 using TripleDES Cipher = TripleDES.Create();
341 Cipher.Mode = CipherMode.CBC;
342 Cipher.Padding = PaddingMode.None;
344 using ICryptoTransform Decryptor = Cipher.CreateDecryptor(Key, IV);
346 return Decryptor.TransformFinalBlock(EncryptedData, 0, EncryptedData.Length);
352 protected static readonly
byte[] zeroIv16 =
new byte[16];
357 protected static readonly
byte[] zeroIv8 =
new byte[8];
Abstract base class for security objects.
Contains methods for simple hash calculations.
static byte[] ComputeSHA1Hash(byte[] Data)
Computes the SHA-1 hash of a block of binary data.
delegate byte[] HashFunctionArray(byte[] Data)
Delegate to hash function.