コード例 #1
0
 internal void Free()
 {
     MarshalExtensions.ZeroMemory(hHash, HashSize);
     MarshalExtensions.ZeroMemory(hBlock, BlockSize);
     Marshal.FreeHGlobal(hHash);
     Marshal.FreeHGlobal(hBlock);
 }
コード例 #2
0
        public unsafe PosixProtectedMemory(int size)
        {
            if (size < 0)
            {
                throw new ArgumentException("Fatal: cannot allocate less than zero.");
            }
            ContentLength = size;
            if (size == 0)
            {
                size = 1;
            }
            uint pageSize = (uint)getpagesize();

            if (pageSize == 0x0)
            {
                Debug.WriteLine("getpagesize() returned 0! Defaulting to 4096 Bytes ...");
                pageSize = 4096;
            }
            uint requiredPages = (uint)Math.Ceiling((double)size / pageSize);

            allocatedSize = requiredPages * pageSize;
            Size          = (int)allocatedSize;
            void *memptr = null;

            _            = posix_memalign(&memptr, pageSize, allocatedSize);
            directHandle = (IntPtr)memptr;
            MarshalExtensions.ZeroMemory(directHandle, Size);
            ContentLength = size;
            _             = mprotect(directHandle, allocatedSize, (int)PROT_FLAGS.PROT_NONE);
        }
        public string ComputeHash(ProtectedMemory protectedMemory)
        {
            IntPtr hash = Digest(protectedMemory);

            byte[] resultBytes = new byte[digestLength];
            Marshal.Copy(hash, resultBytes, 0, digestLength);
            string result = ByteArrayToString(resultBytes);

            MarshalExtensions.ZeroMemory(hash, digestLength);
            Marshal.FreeHGlobal(hash);
            return(result);
        }
コード例 #4
0
        public unsafe (IntPtr, int) ComputeHmacUnsafe(byte *key, int keyLength, byte *message, int messageLength, bool freeKey = false)
        {
            if (keyLength > blockSize)
            {
                (IntPtr reducedKey, _) = ComputeHashUnsafe(key, keyLength);
                return(ComputeHmacUnsafe((byte *)reducedKey, digestLength, message, messageLength, freeKey = true));
            }
            IntPtr hPaddedKey = Marshal.AllocHGlobal(blockSize);

            MarshalExtensions.ZeroMemory(hPaddedKey, blockSize);
            Unsafe.CopyBlock((byte *)hPaddedKey, key, (uint)keyLength);
            if (freeKey)
            {
                MarshalExtensions.ZeroFree((IntPtr)key, keyLength);
            }
            IntPtr hOuterKeyPadded = Marshal.AllocHGlobal(blockSize);
            IntPtr hInnerKeyPadded = Marshal.AllocHGlobal(blockSize);
            byte * outerKeyPadded  = (byte *)hOuterKeyPadded;
            byte * innerKeyPadded  = (byte *)hInnerKeyPadded;

            Unsafe.CopyBlock(outerKeyPadded, (void *)hPaddedKey, blockSize);
            Unsafe.CopyBlock(innerKeyPadded, (void *)hPaddedKey, blockSize);
            MarshalExtensions.ZeroFree(hPaddedKey, blockSize);
            for (int i = 0; i < blockSize; i++)
            {
                outerKeyPadded[i] ^= 0x5c;
            }
            for (int i = 0; i < blockSize; i++)
            {
                innerKeyPadded[i] ^= 0x36;
            }
            int    innerInputLength = blockSize + messageLength;
            IntPtr hInnerInput      = Marshal.AllocHGlobal(innerInputLength);
            byte * innerInput       = (byte *)hInnerInput;

            Unsafe.CopyBlock(innerInput, innerKeyPadded, blockSize);
            MarshalExtensions.ZeroFree(hInnerKeyPadded, blockSize);
            Unsafe.CopyBlock(innerInput + blockSize, message, (uint)messageLength);
            (IntPtr hInnerHash, _) = ComputeHashUnsafe(innerInput, innerInputLength);
            MarshalExtensions.ZeroFree(hInnerInput, innerInputLength);
            const int inputLength = blockSize + digestLength;
            IntPtr    hInput      = Marshal.AllocHGlobal(inputLength);
            byte *    input       = (byte *)hInput;

            Unsafe.CopyBlock(input, outerKeyPadded, blockSize);
            Unsafe.CopyBlock(input + blockSize, (void *)hInnerHash, digestLength);
            (IntPtr hResult, int resultLength) = ComputeHashUnsafe(input, inputLength);
            MarshalExtensions.ZeroFree(hOuterKeyPadded, blockSize);
            MarshalExtensions.ZeroFree(hInnerHash, digestLength);
            MarshalExtensions.ZeroFree(hInput, inputLength);
            return(hResult, resultLength);
        }
        public ProtectedMemory ComputeHashProtected(ProtectedMemory protectedMemory)
        {
            IntPtr          pHash  = Digest(protectedMemory);
            ProtectedMemory result = ProtectedMemory.Allocate(digestLength);

            using (ProtectedMemoryAccess access = new ProtectedMemoryAccess(protectedMemory))
            {
                MarshalExtensions.Copy(pHash, 0, access.Handle, 0, digestLength);
            }
            MarshalExtensions.ZeroMemory(pHash, digestLength);
            Marshal.FreeHGlobal(pHash);
            return(result);
        }
コード例 #6
0
 public PosixFrobnicatedMemory(int size)
 {
     if (size < 0)
     {
         throw new ArgumentException("Fatal: cannot allocate less than zero.");
     }
     ContentLength = size;
     if (size == 0)
     {
         size = 1;
     }
     Size         = size;
     directHandle = Marshal.AllocHGlobal(size);
     MarshalExtensions.ZeroMemory(directHandle, size);
     Protect();
 }
コード例 #7
0
        public Win32EncryptedMemory(int size)
        {
            if (size < 0)
            {
                throw new ArgumentException("Fatal: cannot allocate less than zero.");
            }
            ContentLength = size;
            if (size == 0)
            {
                size = 1;
            }
            uint requiredBlocks = (uint)Math.Ceiling((double)size / CRYPTPROTECTMEMORY_BLOCK_SIZE);

            Size         = (int)(requiredBlocks * CRYPTPROTECTMEMORY_BLOCK_SIZE);
            directHandle = Marshal.AllocHGlobal(Size);
            MarshalExtensions.ZeroMemory(directHandle, Size);
            Protect();
        }
        private unsafe IntPtr Digest(int digestLength, ProtectedMemory protectedMemory)
        {
            Blake2bHashState blake2 = default;

            blake2.Init(digestLength, null);
            int    length = protectedMemory.ContentLength;
            IntPtr hInput = Marshal.AllocHGlobal(length);

            using (ProtectedMemoryAccess access = new ProtectedMemoryAccess(protectedMemory))
            {
                MarshalExtensions.Copy(access.Handle, 0, hInput, 0, length);
            }
            byte *input = (byte *)hInput;

            blake2.Update(input, length);
            MarshalExtensions.ZeroMemory(hInput, length);
            Marshal.FreeHGlobal(hInput);
            IntPtr hash = blake2.Finish();

            blake2.Free();
            return(hash);
        }
コード例 #9
0
        internal unsafe ScryptHashFunction(int costFactor, int blockSizeFactor, int parallelizationFactor, int desiredKeyLength)
        {
            if (desiredKeyLength < 1)
            {
                throw new ArgumentException(nameof(desiredKeyLength) + " must be larger than 0.");
            }
            n              = costFactor;
            r              = blockSizeFactor;
            p              = parallelizationFactor;
            outLength      = desiredKeyLength;
            blockSize      = (uint)(128 * blockSizeFactor);
            blockSizeZeros = new byte[(int)blockSize];
            allocatedSize  = p * (sizeof(byte *) + (int)blockSize);

            hB = Marshal.AllocHGlobal(allocatedSize);
            MarshalExtensions.ZeroMemory(hB, allocatedSize);
            B = (byte **)hB;
            for (int i = 0; i < p; i++)
            {
                long offset = (p * sizeof(byte *)) + (i * blockSize);
                B[i] = (byte *)B + offset;
            }
        }
コード例 #10
0
        internal void Init(int digestLength, ProtectedMemory key)
        {
            uint keyLength = key == null ? 0u : (uint)(key?.ContentLength);

            hHash = Marshal.AllocHGlobal(HashSize);
            hash  = (ulong *)hHash;

            hBlock = Marshal.AllocHGlobal(BlockSize);
            block  = (byte *)hBlock;

            if (digestLength == 0 || (uint)digestLength > HashSize)
            {
                throw new ArgumentOutOfRangeException(nameof(digestLength), "Value must be between 1 and " + HashSize);
            }
            if (keyLength > MaxKeyBytes)
            {
                throw new ArgumentException("Key must be between 0 and " + MaxKeyBytes + " bytes in length", nameof(key));
            }

            outlen = (uint)digestLength;
            fixed(byte *pIv = iv)
            {
                Unsafe.CopyBlock(hash, pIv, HashSize);
            }

            hash[0] ^= 0x01010000u ^ (keyLength << 8) ^ outlen;

            if (keyLength != 0)
            {
                MarshalExtensions.ZeroMemory(hBlock, BlockSize);
                using (ProtectedMemoryAccess access = new ProtectedMemoryAccess(key))
                {
                    Unsafe.CopyBlockUnaligned(block, (byte *)access.Handle, keyLength);
                }
                c = BlockSize;
            }
        }
コード例 #11
0
        public Win32ProtectedMemory(int size)
        {
            if (size < 0)
            {
                throw new ArgumentException("Fatal: cannot allocate less than zero.");
            }
            ContentLength = size;
            if (size == 0)
            {
                size = 1;
            }
            GetNativeSystemInfo(out SYSTEM_INFO systemInfo);
            uint pageSize      = systemInfo.dwPageSize;
            uint requiredPages = (uint)Math.Ceiling((double)size / pageSize);

            allocatedSize = (int)((requiredPages + 2) * pageSize);
            Size          = (int)(requiredPages * pageSize);
            pUsableSize   = new UIntPtr((uint)Size);
            rawHandle     = Marshal.AllocHGlobal(allocatedSize);
            directHandle  = rawHandle + (int)pageSize;
            MarshalExtensions.ZeroMemory(directHandle, Size);
            ContentLength = size;
            Protect();
        }
        private IntPtr Digest(ProtectedMemory protectedMemory)
        {
            // convert string msg into 512-bit blocks (array of 16 32-bit integers) [§5.2.1]
            int    contentLength = protectedMemory.ContentLength;
            double length        = (contentLength / 4) + 3;              // length (in 32-bit integers) of content length + ‘1’ + appended length
            int    blockCount    = (int)Math.Ceiling(length / 16d);      // number of 16-integer (512-bit) blocks required to hold 'l' ints
            int    allocatedSize = blockCount * 16 * sizeof(int);
            IntPtr messageBuffer = Marshal.AllocHGlobal(allocatedSize);

            MarshalExtensions.ZeroMemory(messageBuffer, allocatedSize);
            using (ProtectedMemoryAccess access = new ProtectedMemoryAccess(protectedMemory))
            {
                MarshalExtensions.Copy(access.Handle, 0, messageBuffer, 0, contentLength);
            }
            // append padding
            Marshal.WriteByte(messageBuffer + contentLength, 0x80);
            IntPtr buffer = Marshal.AllocHGlobal(allocatedSize);

            MarshalExtensions.ZeroMemory(buffer, allocatedSize);
            for (int i = 0; i < blockCount; i++)
            {
                IntPtr rowPointer = messageBuffer + (i * 64);
                // encode 4 chars per integer (64 per block), big-endian encoding
                for (int j = 0; j < 16; j++)
                {
                    int value = MarshalExtensions.ReadInt32BigEndian(rowPointer + (j * sizeof(int)));
                    Marshal.WriteInt32(buffer + (sizeof(int) * ((i * 16) + j)), value);
                }
            }
            // zero-free message buffer
            MarshalExtensions.ZeroMemory(messageBuffer, allocatedSize);
            Marshal.FreeHGlobal(messageBuffer);
            // add length (in bits) into final pair of 32-bit integers (big-endian)
            long len   = contentLength * 8;
            int  lenHi = (int)(len >> 32);
            int  lenLo = (int)len;

            Marshal.WriteInt32(buffer + allocatedSize - sizeof(long), lenHi);
            Marshal.WriteInt32(buffer + allocatedSize - sizeof(int), lenLo);

            // allocate message schedule
            IntPtr messageScheduleBuffer = Marshal.AllocHGlobal(msgSchedBufSize);

            // allocate memory for hash and copy constants.
            IntPtr pHash = Marshal.AllocHGlobal(digestLength);

            byte[] managedHash = new byte[H.Length * sizeof(uint)];
            Buffer.BlockCopy(H, 0, managedHash, 0, managedHash.Length);
            Marshal.Copy(managedHash, 0, pHash, managedHash.Length);

            // HASH COMPUTATION
            for (int i = 0; i < blockCount; i++)
            {
                // prepare message schedule
                for (int j = 0; j < 16; j++)
                {
                    int value = Marshal.ReadInt32(buffer + (sizeof(int) * ((i * 16) + j)));
                    Marshal.WriteInt32(messageScheduleBuffer + (j * sizeof(int)), value);
                }
                for (int j = 16; j < 64; j++)
                {
                    uint value = sigma1((uint)Marshal.ReadInt32(messageScheduleBuffer + ((j - 2) * sizeof(int))))
                                 + (uint)Marshal.ReadInt32(messageScheduleBuffer + ((j - 7) * sizeof(int)))
                                 + sigma0((uint)Marshal.ReadInt32(messageScheduleBuffer + ((j - 15) * sizeof(int))))
                                 + (uint)Marshal.ReadInt32(messageScheduleBuffer + ((j - 16) * sizeof(int)));
                    Marshal.WriteInt32(messageScheduleBuffer + (j * sizeof(int)), (int)value);
                }
                // initialize working variables a, b, c, d, e, f, g, h with previous hash value
                uint a = (uint)Marshal.ReadInt32(pHash + (0 * sizeof(int)));
                uint b = (uint)Marshal.ReadInt32(pHash + (1 * sizeof(int)));
                uint c = (uint)Marshal.ReadInt32(pHash + (2 * sizeof(int)));
                uint d = (uint)Marshal.ReadInt32(pHash + (3 * sizeof(int)));
                uint e = (uint)Marshal.ReadInt32(pHash + (4 * sizeof(int)));
                uint f = (uint)Marshal.ReadInt32(pHash + (5 * sizeof(int)));
                uint g = (uint)Marshal.ReadInt32(pHash + (6 * sizeof(int)));
                uint h = (uint)Marshal.ReadInt32(pHash + (7 * sizeof(int)));
                // main loop
                for (int j = 0; j < 64; j++)
                {
                    uint t1 = h + sum1(e) + Ch(e, f, g) + K[j] + (uint)Marshal.ReadInt32(messageScheduleBuffer + (j * sizeof(int)));
                    uint t2 = sum0(a) + Maj(a, b, c);
                    h = g;
                    g = f;
                    f = e;
                    e = d + t1;
                    d = c;
                    c = b;
                    b = a;
                    a = t1 + t2;
                }
                // compute the new intermediate hash value
                Marshal.WriteInt32(pHash + (0 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (0 * sizeof(int))) + a));
                Marshal.WriteInt32(pHash + (1 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (1 * sizeof(int))) + b));
                Marshal.WriteInt32(pHash + (2 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (2 * sizeof(int))) + c));
                Marshal.WriteInt32(pHash + (3 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (3 * sizeof(int))) + d));
                Marshal.WriteInt32(pHash + (4 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (4 * sizeof(int))) + e));
                Marshal.WriteInt32(pHash + (5 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (5 * sizeof(int))) + f));
                Marshal.WriteInt32(pHash + (6 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (6 * sizeof(int))) + g));
                Marshal.WriteInt32(pHash + (7 * sizeof(int)), (int)((uint)Marshal.ReadInt32(pHash + (7 * sizeof(int))) + h));
            }
            MarshalExtensions.Int32LittleEndianArrayToBigEndian(pHash, digestLength);
            // zero-free used buffers
            MarshalExtensions.ZeroMemory(messageScheduleBuffer, msgSchedBufSize);
            Marshal.FreeHGlobal(messageScheduleBuffer);
            MarshalExtensions.ZeroMemory(buffer, allocatedSize);
            Marshal.FreeHGlobal(buffer);
            // return pointer to computed hash (needs to be freed by caller).
            return(pHash);
        }
コード例 #13
0
 public override void Free()
 {
     Unprotect();
     MarshalExtensions.ZeroMemory(directHandle, Size);
     Marshal.FreeHGlobal(rawHandle);
 }
コード例 #14
0
 public void Dispose()
 {
     MarshalExtensions.ZeroMemory(hB, allocatedSize);
     Marshal.FreeHGlobal(hB);
 }