コード例 #1
0
 // Converts a libsodium secret key into a key blob.
 internal virtual int ExportKey(
     SecureMemoryHandle keyHandle,
     KeyBlobFormat format,
     Span <byte> blob)
 {
     throw Error.NotSupported_ExportKey();
 }
コード例 #2
0
ファイル: Interop.Blake2b.cs プロジェクト: relaxar/nsec
 internal static unsafe extern int crypto_generichash_blake2b(
     byte * @out,
     UIntPtr outlen,
     byte * @in,
     ulong inlen,
     SecureMemoryHandle key,
     UIntPtr keylen);
コード例 #3
0
        internal override bool TryImportKey(
            ReadOnlySpan <byte> blob,
            KeyBlobFormat format,
            out SecureMemoryHandle keyHandle,
            out byte[] publicKeyBytes)
        {
            if (format != KeyBlobFormat.RawSymmetricKey)
            {
                throw Error.Argument_FormatNotSupported(nameof(format), format.ToString());
            }

            if (blob.Length < MinKeySize)
            {
                keyHandle      = null;
                publicKeyBytes = null;
                return(false);
            }

            if (blob.Length > SHA256MessageBlockSize)
            {
                publicKeyBytes = null;
                SecureMemoryHandle.Alloc(crypto_hash_sha256_BYTES, out keyHandle);
                crypto_hash_sha256_init(out crypto_hash_sha256_state state);
                crypto_hash_sha256_update(ref state, ref blob.DangerousGetPinnableReference(), (ulong)blob.Length);
                crypto_hash_sha256_final(ref state, keyHandle);
            }
            else
            {
                publicKeyBytes = null;
                SecureMemoryHandle.Alloc(blob.Length, out keyHandle);
                keyHandle.Import(blob);
            }

            return(true);
        }
コード例 #4
0
        public static bool TryImport(
            Algorithm algorithm,
            ReadOnlySpan <byte> blob,
            KeyBlobFormat format,
            KeyFlags flags,
            out Key result)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                success = algorithm.TryImportKey(blob, format, out keyHandle, out publicKeyBytes);
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            result = success ? new Key(algorithm, flags, keyHandle, publicKeyBytes) : null;
            return(success);
        }
コード例 #5
0
 // Creates a new libsodium secret key from a seed.
 internal virtual void CreateKey(
     ReadOnlySpan <byte> seed,
     out SecureMemoryHandle keyHandle,
     out byte[] publicKeyBytes)
 {
     throw Error.NotSupported_CreateKey();
 }
コード例 #6
0
 internal static unsafe extern int crypto_stream_chacha20_ietf_xor_ic(
     byte *c,
     byte *m,
     ulong mlen,
     NSec.Cryptography.Nonce *n,
     uint ic,
     SecureMemoryHandle k);
コード例 #7
0
        internal override bool TryVerifyCore(
            SecureMemoryHandle keyHandle,
            ReadOnlySpan <byte> data,
            ReadOnlySpan <byte> mac)
        {
            Debug.Assert(keyHandle != null);
            Debug.Assert(mac.Length <= crypto_auth_hmacsha256_BYTES);

            // crypto_auth_hmacsha256_verify does not support truncated HMACs,
            // so we calculate the MAC ourselves and call sodium_memcmp to
            // compare the expected MAC with the actual MAC.

            Span <byte> temp;

            try
            {
                unsafe
                {
                    byte *pointer = stackalloc byte[crypto_auth_hmacsha256_BYTES];
                    temp = new Span <byte>(pointer, crypto_auth_hmacsha256_BYTES);
                }

                crypto_auth_hmacsha256_init(out crypto_auth_hmacsha256_state state, keyHandle, (UIntPtr)keyHandle.Length);
                crypto_auth_hmacsha256_update(ref state, ref data.DangerousGetPinnableReference(), (ulong)data.Length);
                crypto_auth_hmacsha256_final(ref state, ref temp.DangerousGetPinnableReference());

                int result = sodium_memcmp(ref temp.DangerousGetPinnableReference(), ref mac.DangerousGetPinnableReference(), (UIntPtr)mac.Length);

                return(result == 0);
            }
            finally
            {
                sodium_memzero(ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);
            }
        }
コード例 #8
0
        public bool TryExportText(
            SecureMemoryHandle keyHandle,
            Span <byte> blob,
            out int blobSize)
        {
            Debug.Assert(keyHandle != null);

            blobSize = _blobTextSize;

            if (blob.Length < blobSize)
            {
                return(false);
            }

            Span <byte> temp = stackalloc byte[_blobSize];

            try
            {
                _blobHeader.CopyTo(temp);
                Serialize(keyHandle, temp.Slice(_blobHeader.Length));

                Armor.EncodeToUtf8(temp, s_beginLabel, s_endLabel, blob);
                return(true);
            }
            finally
            {
                sodium_memzero(ref MemoryMarshal.GetReference(temp), (UIntPtr)temp.Length);
            }
        }
コード例 #9
0
            public static void Alloc(int length, out SecureMemoryHandle handle)
            {
                Debug.Assert(length >= 0);

                handle         = sodium_malloc((UIntPtr)length);
                handle._length = length;
            }
コード例 #10
0
ファイル: SharedSecret.cs プロジェクト: dustinsoftware/nsec
        public static SharedSecret Import(
            ReadOnlySpan <byte> sharedSecret)
        {
            if (sharedSecret.Length > 128)
            {
                throw Error.Argument_SharedSecretLength(nameof(sharedSecret), 128.ToString());
            }

            Sodium.Initialize();

            SecureMemoryHandle sharedSecretHandle = null;
            bool success = false;

            try
            {
                SecureMemoryHandle.Import(sharedSecret, out sharedSecretHandle);
                success = true;
            }
            finally
            {
                if (!success && sharedSecretHandle != null)
                {
                    sharedSecretHandle.Dispose();
                }
            }

            return(new SharedSecret(sharedSecretHandle));
        }
コード例 #11
0
ファイル: PrivateKeyFormatter.cs プロジェクト: judgie79/nsec
        public bool TryExportText(
            SecureMemoryHandle keyHandle,
            Span <byte> blob,
            out int blobSize)
        {
            Debug.Assert(keyHandle != null);

            blobSize = _blobTextSize;

            if (blob.Length < blobSize)
            {
                return(false);
            }

            Span <byte> temp;

            try
            {
                unsafe
                {
                    byte *pointer = stackalloc byte[_blobSize];
                    temp = new Span <byte>(pointer, _blobSize);
                }

                _blobHeader.CopyTo(temp);
                Serialize(keyHandle, temp.Slice(_blobHeader.Length));

                Armor.Encode(temp, s_beginLabel, s_endLabel, blob);
                return(true);
            }
            finally
            {
                sodium_memzero(ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);
            }
        }
コード例 #12
0
ファイル: Blake2bMac.cs プロジェクト: cwharris/nsec
        private protected override bool TryVerifyCore(
            SecureMemoryHandle keyHandle,
            ReadOnlySpan <byte> data,
            ReadOnlySpan <byte> mac)
        {
            Debug.Assert(keyHandle != null);
            Debug.Assert(keyHandle.Length >= crypto_generichash_blake2b_KEYBYTES_MIN);
            Debug.Assert(keyHandle.Length <= crypto_generichash_blake2b_KEYBYTES_MAX);
            Debug.Assert(mac.Length >= crypto_generichash_blake2b_BYTES_MIN);
            Debug.Assert(mac.Length <= crypto_generichash_blake2b_BYTES_MAX);

            Span <byte> temp = stackalloc byte[mac.Length];

            try
            {
                crypto_generichash_blake2b_init(out crypto_generichash_blake2b_state state, keyHandle, (UIntPtr)keyHandle.Length, (UIntPtr)temp.Length);
                crypto_generichash_blake2b_update(ref state, ref data.DangerousGetPinnableReference(), (ulong)data.Length);
                crypto_generichash_blake2b_final(ref state, ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);

                int result = sodium_memcmp(ref temp.DangerousGetPinnableReference(), ref mac.DangerousGetPinnableReference(), (UIntPtr)mac.Length);

                return(result == 0);
            }
            finally
            {
                sodium_memzero(ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);
            }
        }
コード例 #13
0
        private static bool TryVerifyCore(
            SecureMemoryHandle keyHandle,
            ReadOnlySpan <byte> data,
            ReadOnlySpan <byte> hash)
        {
            Debug.Assert(keyHandle != null);
            Debug.Assert(keyHandle.Length >= crypto_generichash_blake2b_KEYBYTES_MIN);
            Debug.Assert(keyHandle.Length <= crypto_generichash_blake2b_KEYBYTES_MAX);
            Debug.Assert(hash.Length >= crypto_generichash_blake2b_BYTES_MIN);
            Debug.Assert(hash.Length <= crypto_generichash_blake2b_BYTES_MAX);

            Span <byte> temp;

            try
            {
                unsafe
                {
                    byte *pointer = stackalloc byte[hash.Length];
                    temp = new Span <byte>(pointer, hash.Length);
                }

                crypto_generichash_blake2b_init(out crypto_generichash_blake2b_state state, keyHandle, (UIntPtr)keyHandle.Length, (UIntPtr)temp.Length);
                crypto_generichash_blake2b_update(ref state, ref data.DangerousGetPinnableReference(), (ulong)data.Length);
                crypto_generichash_blake2b_final(ref state, ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);

                int result = sodium_memcmp(ref temp.DangerousGetPinnableReference(), ref hash.DangerousGetPinnableReference(), (UIntPtr)hash.Length);

                return(result == 0);
            }
            finally
            {
                sodium_memzero(ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);
            }
        }
コード例 #14
0
 public static void Import(
     ReadOnlySpan <byte> span,
     out SecureMemoryHandle handle)
 {
     Alloc(span.Length, out handle);
     handle.Import(span);
 }
コード例 #15
0
ファイル: HmacSha256.cs プロジェクト: dustinsoftware/nsec
        private protected override void MacCore(
            SecureMemoryHandle keyHandle,
            ReadOnlySpan <byte> data,
            Span <byte> mac)
        {
            Debug.Assert(keyHandle != null);
            Debug.Assert(mac.Length <= crypto_auth_hmacsha256_BYTES);

            // crypto_auth_hmacsha256 requires a key with a length of exactly
            // crypto_auth_hmacsha256_KEYBYTES. crypto_auth_hmacsha256_init
            // accepts a key of arbitrary length. So we use _init here.

            // crypto_auth_hmacsha256_init hashes the key if it is larger than
            // the block size.

            crypto_auth_hmacsha256_init(out crypto_auth_hmacsha256_state state, keyHandle, (UIntPtr)keyHandle.Length);
            crypto_auth_hmacsha256_update(ref state, in MemoryMarshal.GetReference(data), (ulong)data.Length);

            // crypto_auth_hmacsha256_final expects an output buffer with a size
            // of exactly crypto_auth_hmacsha256_BYTES, so we need to copy when
            // a truncated output is requested.

            if (mac.Length == crypto_auth_hmacsha256_BYTES)
            {
                crypto_auth_hmacsha256_final(ref state, ref MemoryMarshal.GetReference(mac));
            }
            else
            {
                Span <byte> temp = stackalloc byte[crypto_auth_hmacsha256_BYTES];
                crypto_auth_hmacsha256_final(ref state, ref MemoryMarshal.GetReference(temp));
                temp.Slice(0, mac.Length).CopyTo(mac);
            }
        }
コード例 #16
0
        public int ExportText(
            SecureMemoryHandle keyHandle,
            Span <byte> blob)
        {
            if (blob.Length < _blobTextSize)
            {
                throw new ArgumentException(Error.ArgumentExceptionMessage, nameof(blob));
            }

            Debug.Assert(keyHandle != null);

            Span <byte> temp;

            try
            {
                unsafe
                {
                    byte *pointer = stackalloc byte[_blobSize];
                    temp = new Span <byte>(pointer, _blobSize);
                }

                new ReadOnlySpan <byte>(_blobHeader).CopyTo(temp);
                Serialize(keyHandle, temp.Slice(_blobHeader.Length));
                Armor.Encode(temp, s_beginLabel, s_endLabel, blob.Slice(0, _blobTextSize));
                return(_blobTextSize);
            }
            finally
            {
                sodium_memzero(ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);
            }
        }
コード例 #17
0
ファイル: Key.cs プロジェクト: cwharris/nsec
        public static Key Import(
            Algorithm algorithm,
            ReadOnlySpan <byte> blob,
            KeyBlobFormat format,
            KeyExportPolicies exportPolicy = KeyExportPolicies.None)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                success = algorithm.TryImportKey(blob, format, out keyHandle, out publicKeyBytes);
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            if (!success)
            {
                throw Error.Format_InvalidBlob();
            }

            return(new Key(algorithm, exportPolicy, keyHandle, publicKeyBytes));
        }
コード例 #18
0
ファイル: X25519.cs プロジェクト: wandbond/nsec
 internal override void CreateKey(
     SecureMemoryHandle keyHandle,
     out byte[] publicKeyBytes)
 {
     publicKeyBytes = new byte[crypto_scalarmult_curve25519_SCALARBYTES];
     crypto_scalarmult_curve25519_base(publicKeyBytes, keyHandle);
 }
コード例 #19
0
ファイル: PrivateKeyFormatter.cs プロジェクト: judgie79/nsec
        public bool TryImportText(
            ReadOnlySpan <byte> blob,
            out SecureMemoryHandle keyHandle,
            out byte[] publicKeyBytes)
        {
            Span <byte> temp;

            try
            {
                unsafe
                {
                    byte *pointer = stackalloc byte[_blobSize];
                    temp = new Span <byte>(pointer, _blobSize);
                }

                if (!Armor.TryDecode(blob, s_beginLabel, s_endLabel, temp))
                {
                    keyHandle      = null;
                    publicKeyBytes = null;
                    return(false);
                }

                return(TryImport(temp, out keyHandle, out publicKeyBytes));
            }
            finally
            {
                sodium_memzero(ref temp.DangerousGetPinnableReference(), (UIntPtr)temp.Length);
            }
        }
コード例 #20
0
ファイル: PrivateKeyFormatter.cs プロジェクト: relaxar/nsec
        public bool TryExportText(
            SecureMemoryHandle keyHandle,
            Span <byte> blob,
            out int blobSize)
        {
            blobSize = _blobTextSize;

            if (blob.Length < blobSize)
            {
                return(false);
            }

            Span <byte> temp = stackalloc byte[_blobSize];

            try
            {
                _blobHeader.CopyTo(temp);
                Serialize(keyHandle, temp.Slice(_blobHeader.Length));

                Armor.EncodeToUtf8(temp, s_beginLabel, s_endLabel, blob.Slice(0, _blobTextSize));
                return(true);
            }
            finally
            {
                CryptographicOperations.ZeroMemory(temp);
            }
        }
コード例 #21
0
        internal override void EncryptCore(
            SecureMemoryHandle keyHandle,
            ReadOnlySpan <byte> nonce,
            ReadOnlySpan <byte> associatedData,
            ReadOnlySpan <byte> plaintext,
            Span <byte> ciphertext)
        {
            Debug.Assert(keyHandle != null);
            Debug.Assert(keyHandle.Length == crypto_aead_aes256gcm_KEYBYTES);
            Debug.Assert(nonce.Length == crypto_aead_aes256gcm_NPUBBYTES);
            Debug.Assert(ciphertext.Length == plaintext.Length + crypto_aead_aes256gcm_ABYTES);

            crypto_aead_aes256gcm_encrypt(
                ref ciphertext.DangerousGetPinnableReference(),
                out ulong ciphertextLength,
                ref plaintext.DangerousGetPinnableReference(),
                (ulong)plaintext.Length,
                ref associatedData.DangerousGetPinnableReference(),
                (ulong)associatedData.Length,
                IntPtr.Zero,
                ref nonce.DangerousGetPinnableReference(),
                keyHandle);

            Debug.Assert((ulong)ciphertext.Length == ciphertextLength);
        }
コード例 #22
0
        internal override bool TryDecryptCore(
            SecureMemoryHandle keyHandle,
            ReadOnlySpan <byte> nonce,
            ReadOnlySpan <byte> associatedData,
            ReadOnlySpan <byte> ciphertext,
            Span <byte> plaintext)
        {
            Debug.Assert(keyHandle != null);
            Debug.Assert(keyHandle.Length == crypto_aead_aes256gcm_KEYBYTES);
            Debug.Assert(nonce.Length == crypto_aead_aes256gcm_NPUBBYTES);
            Debug.Assert(plaintext.Length == ciphertext.Length - crypto_aead_aes256gcm_ABYTES);

            int error = crypto_aead_aes256gcm_decrypt(
                ref plaintext.DangerousGetPinnableReference(),
                out ulong plaintextLength,
                IntPtr.Zero,
                ref ciphertext.DangerousGetPinnableReference(),
                (ulong)ciphertext.Length,
                ref associatedData.DangerousGetPinnableReference(),
                (ulong)associatedData.Length,
                ref nonce.DangerousGetPinnableReference(),
                keyHandle);

            // libsodium clears the plaintext if decryption fails.

            Debug.Assert(error != 0 || (ulong)plaintext.Length == plaintextLength);
            return(error == 0);
        }
コード例 #23
0
 // Converts a key blob into a libsodium secret key.
 internal virtual bool TryImportKey(
     ReadOnlySpan <byte> blob,
     KeyBlobFormat format,
     out SecureMemoryHandle keyHandle,
     out byte[] publicKeyBytes)
 {
     throw Error.NotSupported_ImportKey();
 }
コード例 #24
0
ファイル: HmacSha256.cs プロジェクト: relaxar/nsec
 internal override void CreateKey(
     ReadOnlySpan <byte> seed,
     out SecureMemoryHandle keyHandle,
     out PublicKey?publicKey)
 {
     publicKey = null;
     keyHandle = SecureMemoryHandle.CreateFrom(seed);
 }
コード例 #25
0
ファイル: HmacSha256.cs プロジェクト: dustinsoftware/nsec
 internal override void CreateKey(
     ReadOnlySpan <byte> seed,
     out SecureMemoryHandle keyHandle,
     out byte[] publicKeyBytes)
 {
     publicKeyBytes = null;
     SecureMemoryHandle.Import(seed, out keyHandle);
 }
コード例 #26
0
 // Converts a libsodium secret key into a key blob.
 internal virtual bool TryExportKey(
     SecureMemoryHandle keyHandle,
     KeyBlobFormat format,
     Span <byte> blob,
     out int blobSize)
 {
     throw Error.NotSupported_ExportKey();
 }
コード例 #27
0
        public Key DeriveKey(
            SharedSecret sharedSecret,
            ReadOnlySpan <byte> salt,
            ReadOnlySpan <byte> info,
            Algorithm algorithm,
            KeyExportPolicies exportPolicy = KeyExportPolicies.None)
        {
            if (sharedSecret == null)
            {
                throw Error.ArgumentNull_SharedSecret(nameof(sharedSecret));
            }
            if (!_supportsSalt && !salt.IsEmpty)
            {
                throw Error.Argument_SaltNotSupported(nameof(salt));
            }
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            int seedSize = algorithm.GetDefaultSeedSize();

            if (seedSize > MaxOutputSize)
            {
                throw Error.NotSupported_CreateKey();
            }
            Debug.Assert(seedSize <= 64);

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                Span <byte> seed = stackalloc byte[seedSize];
                try
                {
                    DeriveBytesCore(sharedSecret.Handle, salt, info, seed);
                    algorithm.CreateKey(seed, out keyHandle, out publicKeyBytes);
                    success = true;
                }
                finally
                {
                    sodium_memzero(ref seed.DangerousGetPinnableReference(), (UIntPtr)seed.Length);
                }
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            return(new Key(algorithm, exportPolicy, keyHandle, publicKeyBytes));
        }
コード例 #28
0
        protected override void Serialize(
            SecureMemoryHandle keyHandle,
            Span <byte> span)
        {
            Debug.Assert(keyHandle.Size == crypto_scalarmult_curve25519_SCALARBYTES);
            Debug.Assert(span.Length == crypto_scalarmult_curve25519_SCALARBYTES);

            keyHandle.CopyTo(span);
        }
コード例 #29
0
ファイル: SharedSecret.cs プロジェクト: dustinsoftware/nsec
        internal SharedSecret(
            SecureMemoryHandle sharedSecretHandle)
        {
            Debug.Assert(sharedSecretHandle != null);

            sharedSecretHandle.MakeReadOnly();

            _handle = sharedSecretHandle;
        }
コード例 #30
0
        internal override void CreateKey(
            ReadOnlySpan <byte> seed,
            out SecureMemoryHandle keyHandle,
            out PublicKey?publicKey)
        {
            Debug.Assert(seed.Length == crypto_aead_chacha20poly1305_ietf_KEYBYTES);

            publicKey = null;
            keyHandle = SecureMemoryHandle.CreateFrom(seed);
        }