internal void Free() { MarshalExtensions.ZeroMemory(hHash, HashSize); MarshalExtensions.ZeroMemory(hBlock, BlockSize); Marshal.FreeHGlobal(hHash); Marshal.FreeHGlobal(hBlock); }
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); }
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); }
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(); }
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); }
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; } }
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; } }
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); }
public override void Free() { Unprotect(); MarshalExtensions.ZeroMemory(directHandle, Size); Marshal.FreeHGlobal(rawHandle); }
public void Dispose() { MarshalExtensions.ZeroMemory(hB, allocatedSize); Marshal.FreeHGlobal(hB); }