Merge branch 'master' into memmgr
This commit is contained in:
@@ -49,6 +49,10 @@
|
||||
#define PFL_DIGIT_PRECISION 0x00002000
|
||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||
|
||||
/* Cryptographic related definitions */
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
/* Runtime Library routine callbacks */
|
||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||
@@ -95,4 +99,12 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
|
||||
LONG Flags;
|
||||
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
||||
|
||||
/* Runtime Library SHA-1 context structure definition */
|
||||
typedef struct _RTL_SHA1_CONTEXT
|
||||
{
|
||||
ULONG State[5];
|
||||
ULONG Count[2];
|
||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
||||
|
||||
#endif /* __XTDK_RTLTYPES_H */
|
||||
|
||||
@@ -80,6 +80,10 @@
|
||||
/* Macro that returns offset of the virtual address */
|
||||
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
|
||||
|
||||
/* Macros for bitwise rotating */
|
||||
#define ROTATE_LEFT(Value, Count) ((Value << Count) | (Value >> (32 - Count)))
|
||||
#define ROTATE_RIGHT(Value, Count) ((Value >> Count) | (Value << (32 - Count)))
|
||||
|
||||
/* Macro for rounding down */
|
||||
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
|
||||
|
||||
@@ -104,7 +108,7 @@
|
||||
|
||||
/* Variadic ABI functions */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
#define VA_ARG(Marker, Type) ((sizeof (Type) < sizeof(UINT_PTR)) ? \
|
||||
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||
(Type)(__builtin_va_arg(Marker, Type)))
|
||||
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)
|
||||
|
||||
@@ -79,6 +79,8 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <rtl/llist.hh>
|
||||
#include <rtl/math.hh>
|
||||
#include <rtl/memory.hh>
|
||||
#include <rtl/sha1.hh>
|
||||
#include <rtl/slist.hh>
|
||||
#include <rtl/string.hh>
|
||||
#include <rtl/widestr.hh>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: xtoskrnl/includes/rtl/llist.hh
|
||||
* DESCRIPTION: Linked list manipulation routines
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
* Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_RTL_LLIST_HH
|
||||
@@ -18,6 +19,7 @@ namespace RTL
|
||||
class LinkedList
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
|
||||
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||
@@ -27,6 +29,10 @@ namespace RTL
|
||||
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
|
||||
STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN OUT PLIST_ENTRY SpliceList);
|
||||
STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN OUT PLIST_ENTRY SpliceList);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
37
xtoskrnl/includes/rtl/sha1.hh
Normal file
37
xtoskrnl/includes/rtl/sha1.hh
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/rtl/sha1.hh
|
||||
* DESCRIPTION: SHA1 computation support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_RTL_SHA1_HH
|
||||
#define __XTOSKRNL_RTL_SHA1_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Runtime Library */
|
||||
namespace RTL
|
||||
{
|
||||
class SHA1
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI XTSTATUS ComputeDigest(IN PCUCHAR Buffer,
|
||||
IN SIZE_T BufferSize,
|
||||
OUT PUCHAR Digest);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
|
||||
OUT PUCHAR Digest);
|
||||
STATIC XTAPI VOID HashData(IN OUT PRTL_SHA1_CONTEXT Context,
|
||||
IN PCUCHAR Data,
|
||||
IN ULONG Length);
|
||||
STATIC XTAPI XTSTATUS InitializeContext(OUT PRTL_SHA1_CONTEXT Context);
|
||||
STATIC XTAPI VOID TransformData(IN OUT PULONG State,
|
||||
IN PCUCHAR Buffer);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_RTL_SHA1_HH */
|
||||
38
xtoskrnl/includes/rtl/slist.hh
Normal file
38
xtoskrnl/includes/rtl/slist.hh
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/rtl/slist.hh
|
||||
* DESCRIPTION: Singly linked list manipulation routines
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_RTL_SLIST_HH
|
||||
#define __XTOSKRNL_RTL_SLIST_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Runtime Library */
|
||||
namespace RTL
|
||||
{
|
||||
class SinglyList
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL PSINGLE_LIST_ENTRY GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
|
||||
STATIC XTCDECL VOID InitializeListHead(IN PSINGLE_LIST_HEADER ListHead);
|
||||
STATIC XTCDECL VOID InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN PSINGLE_LIST_ENTRY Entry);
|
||||
STATIC XTCDECL VOID InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN PSINGLE_LIST_ENTRY Entry);
|
||||
STATIC XTCDECL BOOLEAN ListEmpty(IN PSINGLE_LIST_HEADER ListHead);
|
||||
STATIC XTAPI USHORT QueryListDepth(IN PSINGLE_LIST_HEADER ListHead);
|
||||
STATIC XTCDECL VOID RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
|
||||
IN PSINGLE_LIST_ENTRY Entry);
|
||||
STATIC XTCDECL VOID SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN OUT PSINGLE_LIST_HEADER SpliceList);
|
||||
STATIC XTCDECL VOID SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN OUT PSINGLE_LIST_HEADER SpliceList);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_RTL_SLIST_HH */
|
||||
@@ -2,7 +2,7 @@
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/rtl/llist.cc
|
||||
* DESCRIPTION: Linked list manipulation routines
|
||||
* DESCRIPTION: Doubly linked list manipulation routines
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
@@ -10,10 +10,35 @@
|
||||
|
||||
|
||||
/**
|
||||
* This routine initializes a structure representing the head of a double-linked list.
|
||||
* Retrieves the first entry from a doubly linked list without removing it from the list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Pointer to a structure that serves as the list header.
|
||||
* Supplies a pointer to a structure that serves as the list header.
|
||||
*
|
||||
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
PLIST_ENTRY
|
||||
RTL::LinkedList::GetFirstEntry(IN PLIST_ENTRY ListHead)
|
||||
{
|
||||
/* Check if the list is empty */
|
||||
if(ListEmpty(ListHead))
|
||||
{
|
||||
/* Empty list, return NULLPTR */
|
||||
return NULLPTR;
|
||||
}
|
||||
|
||||
/* Return first entry in the list */
|
||||
return ListHead->Flink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a structure representing the head of a doubly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that serves as the list header.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -23,15 +48,16 @@ XTCDECL
|
||||
VOID
|
||||
RTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead)
|
||||
{
|
||||
/* Initialize list head */
|
||||
ListHead->Blink = ListHead;
|
||||
ListHead->Flink = ListHead;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes a structure representing the head of a 32bit double-linked list.
|
||||
* Initializes a structure representing the head of a 32bit doubly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Pointer to a structure that serves as the list header.
|
||||
* Supplies a pointer to a structure that serves as the list header.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -41,18 +67,19 @@ XTCDECL
|
||||
VOID
|
||||
RTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead)
|
||||
{
|
||||
/* Initialize list head */
|
||||
ListHead->Blink = PtrToUlong(ListHead);
|
||||
ListHead->Flink = PtrToUlong(ListHead);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine inserts an entry at the head of a doubly linked list.
|
||||
* Inserts an entry at the head of a doubly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Pointer to the head of the list.
|
||||
* Supplies a pointer to the head of the list.
|
||||
*
|
||||
* @param Entry
|
||||
* Pointer to the entry that will be inserted in the list.
|
||||
* Supplies a pointer to the entry that will be inserted in the list.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -63,6 +90,7 @@ VOID
|
||||
RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY Entry)
|
||||
{
|
||||
/* Insert entry at the head of the list */
|
||||
Entry->Flink = ListHead->Flink;
|
||||
Entry->Blink = ListHead;
|
||||
ListHead->Flink->Blink = Entry;
|
||||
@@ -70,13 +98,13 @@ RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine inserts an entry at the tail of a doubly linked list.
|
||||
* Inserts an entry at the tail of a doubly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Pointer to the head of the list.
|
||||
* Supplies a pointer to the head of the list.
|
||||
*
|
||||
* @param Entry
|
||||
* Pointer to the entry that will be inserted in the list.
|
||||
* Supplies a pointer to the entry that will be inserted in the list.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -87,6 +115,7 @@ VOID
|
||||
RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY Entry)
|
||||
{
|
||||
/* Insert entry at the tail of the list */
|
||||
Entry->Flink = ListHead;
|
||||
Entry->Blink = ListHead->Blink;
|
||||
ListHead->Blink->Flink = Entry;
|
||||
@@ -97,9 +126,9 @@ RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
|
||||
* Indicates whether a doubly linked list structure is empty, or not initialized at all.
|
||||
*
|
||||
* @param ListHead
|
||||
* Pointer to a structure that represents the head of the list.
|
||||
* Supplies a pointer to a structure that represents the head of the list.
|
||||
*
|
||||
* @return TRUE if there are currently no entries in the list or FALSE otherwise.
|
||||
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -107,14 +136,15 @@ XTCDECL
|
||||
BOOLEAN
|
||||
RTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead)
|
||||
{
|
||||
/* Check if the list is empty */
|
||||
return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead));
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine detects a loop in a doubly linked list.
|
||||
* Detects a loop in a doubly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Pointer to a structure that represents the head of the list.
|
||||
* Supplies a pointer to a structure that represents the head of the list.
|
||||
*
|
||||
* @return TRUE if linked list contains a loop or FALSE otherwise.
|
||||
*
|
||||
@@ -157,10 +187,10 @@ RTL::LinkedList::ListLoop(IN PLIST_ENTRY ListHead)
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine removes an entry from a doubly linked list.
|
||||
* Removes an entry from a doubly linked list.
|
||||
*
|
||||
* @param Entry
|
||||
* Pointer to the entry that will be removed from the list.
|
||||
* Supplies a pointer to the entry that will be removed from the list.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -170,6 +200,91 @@ XTCDECL
|
||||
VOID
|
||||
RTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry)
|
||||
{
|
||||
/* Remove entry from the list */
|
||||
Entry->Flink->Blink = Entry->Blink;
|
||||
Entry->Blink->Flink = Entry->Flink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splices a doubly linked list at the head of another list. The source list is reinitialized to empty.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that represents the head of the list.
|
||||
*
|
||||
* @param SpliceList
|
||||
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::LinkedList::SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN OUT PLIST_ENTRY SpliceList)
|
||||
{
|
||||
PLIST_ENTRY FirstEntry, LastEntry;
|
||||
|
||||
/* Check if the list to splice is empty */
|
||||
if(SpliceList->Flink == SpliceList)
|
||||
{
|
||||
/* Nothing to splice, return */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get first and last entries of the list to splice */
|
||||
FirstEntry = SpliceList->Flink;
|
||||
LastEntry = SpliceList->Blink;
|
||||
|
||||
/* Splice the list at the head of destination */
|
||||
FirstEntry->Blink = ListHead;
|
||||
LastEntry->Flink = ListHead->Flink;
|
||||
ListHead->Flink->Blink = LastEntry;
|
||||
ListHead->Flink = FirstEntry;
|
||||
|
||||
/* Reinitialize the source list to empty */
|
||||
SpliceList->Blink = SpliceList;
|
||||
SpliceList->Flink = SpliceList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splices a doubly linked list at the tail of another list. The source list is reinitialized to empty.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to the head of the destination list.
|
||||
*
|
||||
* @param SpliceList
|
||||
* Supplies a pointer to the head of the list that will be spliced.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::LinkedList::SpliceTailList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN OUT PLIST_ENTRY SpliceList)
|
||||
{
|
||||
PLIST_ENTRY FirstEntry, LastEntry;
|
||||
|
||||
/* Check if the list to splice is empty */
|
||||
if(SpliceList->Flink == SpliceList)
|
||||
{
|
||||
/* Nothing to splice, return */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get first and last entries of the list to splice */
|
||||
FirstEntry = SpliceList->Flink;
|
||||
LastEntry = SpliceList->Blink;
|
||||
|
||||
/* Splice the list at the tail of destination */
|
||||
FirstEntry->Blink = ListHead->Blink;
|
||||
LastEntry->Flink = ListHead;
|
||||
ListHead->Blink->Flink = FirstEntry;
|
||||
ListHead->Blink = LastEntry;
|
||||
|
||||
/* Reinitialize the source list to empty */
|
||||
SpliceList->Blink = SpliceList;
|
||||
SpliceList->Flink = SpliceList;
|
||||
}
|
||||
|
||||
322
xtoskrnl/rtl/sha1.cc
Normal file
322
xtoskrnl/rtl/sha1.cc
Normal file
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/rtl/sha1.cc
|
||||
* DESCRIPTION: SHA1 computation support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Computes the SHA-1 hash of a buffer in a single step.
|
||||
*
|
||||
* @param Buffer
|
||||
* Supplies a pointer to the buffer containing the data to be hashed.
|
||||
*
|
||||
* @param BufferSize
|
||||
* Specifies the size of the buffer in bytes.
|
||||
*
|
||||
* @param Digest
|
||||
* Supplies a pointer to the buffer that receives the 20-byte SHA-1 hash digest.
|
||||
*
|
||||
* @return This routine returns STATUS_SUCCESS if the hash was computed successfully,
|
||||
* or STATUS_INVALID_PARAMETER if an invalid parameter was supplied.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
RTL::SHA1::ComputeDigest(IN PCUCHAR Buffer,
|
||||
IN SIZE_T BufferSize,
|
||||
OUT PUCHAR Digest)
|
||||
{
|
||||
RTL_SHA1_CONTEXT Context;
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Validate input parameters */
|
||||
if(!Digest || (!Buffer && BufferSize > 0))
|
||||
{
|
||||
/* Invalid parameters, return error */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Initialize SHA-1 context */
|
||||
Status = InitializeContext(&Context);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to initialize SHA-1 context, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Hash data and compute SHA-1 digest */
|
||||
HashData(&Context, Buffer, BufferSize);
|
||||
ComputeHash(&Context, Digest);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes the SHA-1 hash computation and provides the digest.
|
||||
*
|
||||
* @param Context
|
||||
* Supplies a pointer to the SHA-1 context structure.
|
||||
*
|
||||
* @param Digest
|
||||
* Supplies a pointer to a buffer that receives the 20-byte SHA-1 hash digest.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::SHA1::ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
|
||||
OUT PUCHAR Digest)
|
||||
{
|
||||
ULONG Index, PaddingLength;
|
||||
UCHAR Padding[64];
|
||||
UCHAR Bits[8];
|
||||
|
||||
/* Zero padding and append 0x80 to it */
|
||||
RTL::Memory::ZeroMemory(Padding, 64);
|
||||
Padding[0] = 0x80;
|
||||
|
||||
/* Encode the total message length in bits as a Big Endian 64-bit integer */
|
||||
*(PULONG)(Bits) = RTL::Endianness::SwapByte32(Context->Count[1]);
|
||||
*(PULONG)(Bits + 4) = RTL::Endianness::SwapByte32(Context->Count[0]);
|
||||
|
||||
/* Calculate padding length needed to align the message to 56 bytes */
|
||||
Index = (Context->Count[0] >> 3) & 0x3F;
|
||||
PaddingLength = (Index < 56) ? (56 - Index) : (120 - Index);
|
||||
|
||||
/* Append the padding bytes to the message stream to satisfy the block boundary */
|
||||
HashData(Context, Padding, PaddingLength);
|
||||
|
||||
/* Append bits before final transformation */
|
||||
HashData(Context, Bits, 8);
|
||||
|
||||
/* Store hash to output in Big Endian format */
|
||||
Digest[0] = (UCHAR)((Context->State[0] >> 24) & 0xFF);
|
||||
Digest[1] = (UCHAR)((Context->State[0] >> 16) & 0xFF);
|
||||
Digest[2] = (UCHAR)((Context->State[0] >> 8) & 0xFF);
|
||||
Digest[3] = (UCHAR)(Context->State[0] & 0xFF);
|
||||
Digest[4] = (UCHAR)((Context->State[1] >> 24) & 0xFF);
|
||||
Digest[5] = (UCHAR)((Context->State[1] >> 16) & 0xFF);
|
||||
Digest[6] = (UCHAR)((Context->State[1] >> 8) & 0xFF);
|
||||
Digest[7] = (UCHAR)(Context->State[1] & 0xFF);
|
||||
Digest[8] = (UCHAR)((Context->State[2] >> 24) & 0xFF);
|
||||
Digest[9] = (UCHAR)((Context->State[2] >> 16) & 0xFF);
|
||||
Digest[10] = (UCHAR)((Context->State[2] >> 8) & 0xFF);
|
||||
Digest[11] = (UCHAR)(Context->State[2] & 0xFF);
|
||||
Digest[12] = (UCHAR)((Context->State[3] >> 24) & 0xFF);
|
||||
Digest[13] = (UCHAR)((Context->State[3] >> 16) & 0xFF);
|
||||
Digest[14] = (UCHAR)((Context->State[3] >> 8) & 0xFF);
|
||||
Digest[15] = (UCHAR)(Context->State[3] & 0xFF);
|
||||
Digest[16] = (UCHAR)((Context->State[4] >> 24) & 0xFF);
|
||||
Digest[17] = (UCHAR)((Context->State[4] >> 16) & 0xFF);
|
||||
Digest[18] = (UCHAR)((Context->State[4] >> 8) & 0xFF);
|
||||
Digest[19] = (UCHAR)(Context->State[4] & 0xFF);
|
||||
|
||||
/* Clear context memory for security */
|
||||
RTL::Memory::ZeroMemory(Context, sizeof(RTL_SHA1_CONTEXT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the SHA-1 context with the provided data buffer.
|
||||
*
|
||||
* @param Context
|
||||
* Supplies a pointer to the SHA-1 context structure.
|
||||
*
|
||||
* @param Data
|
||||
* Supplies a pointer to the buffer containing the data to be hashed.
|
||||
*
|
||||
* @param Length
|
||||
* Specifies the length of the data buffer in bytes.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::SHA1::HashData(IN OUT PRTL_SHA1_CONTEXT Context,
|
||||
IN PCUCHAR Data,
|
||||
IN ULONG Length)
|
||||
{
|
||||
ULONG Index, Input, PartialLength;
|
||||
|
||||
/* Calculate byte offset within the 64-byte block buffer */
|
||||
Index = (Context->Count[0] >> 3) & 0x3F;
|
||||
|
||||
/* Update the total bit count, handling overflow from low to high word */
|
||||
if((Context->Count[0] += (Length << 3)) < (Length << 3))
|
||||
{
|
||||
/* Increment high 32-bit counter on low counter overflow */
|
||||
Context->Count[1]++;
|
||||
}
|
||||
|
||||
/* Add the high-order bits of the length (bytes -> bits overflow) to the high counter */
|
||||
Context->Count[1] += (Length >> 29);
|
||||
|
||||
/* Calculate the number of bytes required to fill the remaining buffer space */
|
||||
PartialLength = 64 - Index;
|
||||
|
||||
/* Transform as many times as possible */
|
||||
if(Length >= PartialLength)
|
||||
{
|
||||
/* Fill the buffer partially and transform */
|
||||
RTL::Memory::CopyMemory(&Context->Buffer[Index], Data, PartialLength);
|
||||
TransformData(Context->State, Context->Buffer);
|
||||
|
||||
/* Process remaining full 64-byte blocks directly from the input pointer */
|
||||
for(Input = PartialLength; Input + 63 < Length; Input += 64)
|
||||
{
|
||||
/* Transform the full block without copying to the internal buffer */
|
||||
TransformData(Context->State, &Data[Input]);
|
||||
}
|
||||
|
||||
/* Reset buffer index to indicate the buffer is now empty */
|
||||
Index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No full block was formed, begin copying from the start of input */
|
||||
Input = 0;
|
||||
}
|
||||
|
||||
/* Buffer remaining input */
|
||||
RTL::Memory::CopyMemory(&Context->Buffer[Index], &Data[Input], Length - Input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a SHA-1 context structure with the standard initial hash values.
|
||||
*
|
||||
* @param Context
|
||||
* Supplies a pointer to the SHA-1 context structure to initialize.
|
||||
*
|
||||
* @return This routine returns STATUS_SUCCESS if the context was initialized successfully,
|
||||
* or STATUS_INVALID_PARAMETER if the pointer is NULLPTR.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
RTL::SHA1::InitializeContext(OUT PRTL_SHA1_CONTEXT Context)
|
||||
{
|
||||
/* Validate input parameter */
|
||||
if(!Context)
|
||||
{
|
||||
/* Invalid parameter, return error */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Initialize hash constants defined by FIPS 180-4 */
|
||||
Context->State[0] = 0x67452301;
|
||||
Context->State[1] = 0xEFCDAB89;
|
||||
Context->State[2] = 0x98BADCFE;
|
||||
Context->State[3] = 0x10325476;
|
||||
Context->State[4] = 0xC3D2E1F0;
|
||||
Context->Count[0] = 0;
|
||||
Context->Count[1] = 0;
|
||||
|
||||
/* Clear buffer */
|
||||
RTL::Memory::ZeroMemory(Context->Buffer, SHA1_BLOCK_SIZE);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a single 64-byte block using the SHA-1 compression function.
|
||||
*
|
||||
* @param State
|
||||
* Supplies a pointer to the array containing the current hash state variables.
|
||||
*
|
||||
* @param Buffer
|
||||
* Supplies a pointer to the 64-byte input buffer to be transformed.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::SHA1::TransformData(IN OUT PULONG State,
|
||||
IN PCUCHAR Buffer)
|
||||
{
|
||||
ULONG Constant, Function, Index, TempHash;
|
||||
ULONG TempState[5];
|
||||
ULONG Stack[80];
|
||||
|
||||
/* Initialize working variables with current state */
|
||||
TempState[0] = State[0];
|
||||
TempState[1] = State[1];
|
||||
TempState[2] = State[2];
|
||||
TempState[3] = State[3];
|
||||
TempState[4] = State[4];
|
||||
|
||||
/* Initialize the first 16 words of the message schedule from the input buffer */
|
||||
for(Index = 0; Index < 16; Index++)
|
||||
{
|
||||
/* Convert input words from Little Endian to Big Endian required by SHA-1 */
|
||||
Stack[Index] = RTL::Endianness::SwapByte32(((const PULONG)Buffer)[Index]);
|
||||
}
|
||||
|
||||
/* Expand the message to 80 words using the SHA-1 algorithm */
|
||||
for(Index = 16; Index < 80; Index++)
|
||||
{
|
||||
/* Compute the next word value based on XOR and left rotation */
|
||||
Stack[Index] = ROTATE_LEFT((Stack[Index - 3] ^ Stack[Index - 8] ^ Stack[Index - 14] ^ Stack[Index - 16]), 1);
|
||||
}
|
||||
|
||||
/* Execute the main compression loop for 80 rounds */
|
||||
for(Index = 0; Index < 80; Index++)
|
||||
{
|
||||
/* Determine the logical function and constant based on the current round */
|
||||
if(Index < 20)
|
||||
{
|
||||
/* Set the constant defined by FIPS 180-4 for rounds 0-19 and calculate the logical function */
|
||||
Constant = 0x5A827999;
|
||||
Function = (TempState[1] & TempState[2]) | ((~TempState[1]) & TempState[3]);
|
||||
}
|
||||
else if(Index < 40)
|
||||
{
|
||||
/* Set the constant defined by FIPS 180-4 for rounds 20-39 and calculate the logical function */
|
||||
Constant = 0x6ED9EBA1;
|
||||
Function = TempState[1] ^ TempState[2] ^ TempState[3];
|
||||
}
|
||||
else if(Index < 60)
|
||||
{
|
||||
/* Set the constant defined by FIPS 180-4 for rounds 40-59 and calculate the logical function */
|
||||
Constant = 0x8F1BBCDC;
|
||||
Function = (TempState[1] & TempState[2]) | (TempState[1] & TempState[3]) | (TempState[2] & TempState[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the constant defined by FIPS 180-4 for rounds 60-79 and calculate the logical function */
|
||||
Constant = 0xCA62C1D6;
|
||||
Function = TempState[1] ^ TempState[2] ^ TempState[3];
|
||||
}
|
||||
|
||||
/* Calculate the temporary hash value for this round */
|
||||
TempHash = ROTATE_LEFT(TempState[0], 5) + Function + TempState[4] + Constant + Stack[Index];
|
||||
TempState[4] = TempState[3];
|
||||
TempState[3] = TempState[2];
|
||||
TempState[2] = ROTATE_LEFT(TempState[1], 30);
|
||||
TempState[1] = TempState[0];
|
||||
TempState[0] = TempHash;
|
||||
}
|
||||
|
||||
/* Add the compressed chunk to the current hash value */
|
||||
State[0] += TempState[0];
|
||||
State[1] += TempState[1];
|
||||
State[2] += TempState[2];
|
||||
State[3] += TempState[3];
|
||||
State[4] += TempState[4];
|
||||
|
||||
/* Clear sensitive data from stack */
|
||||
RTL::Memory::ZeroMemory(Stack, sizeof(Stack));
|
||||
}
|
||||
327
xtoskrnl/rtl/slist.cc
Normal file
327
xtoskrnl/rtl/slist.cc
Normal file
@@ -0,0 +1,327 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/rtl/slist.cc
|
||||
* DESCRIPTION: Singly linked list manipulation routines
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the first entry from a singly linked list without removing it from the list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that serves as the list header.
|
||||
*
|
||||
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
PSINGLE_LIST_ENTRY
|
||||
RTL::SinglyList::GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead)
|
||||
{
|
||||
/* Check if the list is empty */
|
||||
if(ListEmpty(ListHead))
|
||||
{
|
||||
/* Empty list, return NULLPTR */
|
||||
return NULLPTR;
|
||||
}
|
||||
|
||||
/* Return first entry in the list */
|
||||
return ListHead->Next.Next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a structure representing the head of a singly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that serves as the list header.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::SinglyList::InitializeListHead(IN PSINGLE_LIST_HEADER ListHead)
|
||||
{
|
||||
/* Initialize the list head */
|
||||
ListHead->Alignment = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an entry at the head of a singly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to the head of the list.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies a pointer to the entry that will be inserted in the list.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::SinglyList::InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN PSINGLE_LIST_ENTRY Entry)
|
||||
{
|
||||
/* Insert entry at the head of the list and increment depth */
|
||||
Entry->Next = ListHead->Next.Next;
|
||||
ListHead->Next.Next = Entry;
|
||||
ListHead->Depth++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an entry at the tail of a singly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to the head of the list.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies a pointer to the entry that will be inserted in the list.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::SinglyList::InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN PSINGLE_LIST_ENTRY Entry)
|
||||
{
|
||||
PSINGLE_LIST_ENTRY CurrentEntry;
|
||||
|
||||
/* Set Next pointer of the new entry to NULLPTR */
|
||||
Entry->Next = NULLPTR;
|
||||
|
||||
/* Check if the list is empty */
|
||||
if(ListEmpty(ListHead))
|
||||
{
|
||||
/* Insert entry at the head */
|
||||
ListHead->Next.Next = Entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Traverse the list to find the last entry */
|
||||
CurrentEntry = ListHead->Next.Next;
|
||||
while(CurrentEntry->Next != NULLPTR)
|
||||
{
|
||||
/* Move to the next entry */
|
||||
CurrentEntry = CurrentEntry->Next;
|
||||
}
|
||||
|
||||
/* Insert entry at the tail */
|
||||
CurrentEntry->Next = Entry;
|
||||
}
|
||||
|
||||
/* Increment list depth */
|
||||
ListHead->Depth++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a singly linked list structure is empty, or not initialized at all.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that represents the head of the list.
|
||||
*
|
||||
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
RTL::SinglyList::ListEmpty(IN PSINGLE_LIST_HEADER ListHead)
|
||||
{
|
||||
/* Check if the list is empty */
|
||||
return (ListHead == NULLPTR || ListHead->Next.Next == NULLPTR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the current depth (number of entries) of a singly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that represents the head of the singly linked list.
|
||||
*
|
||||
* @return This routine returns the number of entries currently in the list, or zero if the list head is NULLPTR.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
USHORT
|
||||
RTL::SinglyList::QueryListDepth(IN PSINGLE_LIST_HEADER ListHead)
|
||||
{
|
||||
/* Check if the list head is initialized and valid */
|
||||
if(ListHead == NULLPTR)
|
||||
{
|
||||
/* Return zero */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the list depth */
|
||||
return ListHead->Depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an entry from a singly linked list.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to the head of the list.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies a pointer to the entry that will be removed from the list.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::SinglyList::RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
|
||||
IN PSINGLE_LIST_ENTRY Entry)
|
||||
{
|
||||
PSINGLE_LIST_ENTRY PreviousEntry;
|
||||
|
||||
/* Check if the list is empty */
|
||||
if(ListEmpty(ListHead))
|
||||
{
|
||||
/* List is empty, nothing to remove */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the entry is the first one */
|
||||
if(ListHead->Next.Next == Entry)
|
||||
{
|
||||
/* Remove the first entry and decrement depth */
|
||||
ListHead->Next.Next = Entry->Next;
|
||||
ListHead->Depth--;
|
||||
|
||||
/* Nothing else to do */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the previous entry */
|
||||
PreviousEntry = ListHead->Next.Next;
|
||||
while(PreviousEntry->Next != Entry)
|
||||
{
|
||||
/* Move to the next entry */
|
||||
PreviousEntry = PreviousEntry->Next;
|
||||
|
||||
/* Check if we reached the end of the list */
|
||||
if(PreviousEntry == NULLPTR)
|
||||
{
|
||||
/* Entry not found */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the entry and decrement depth */
|
||||
PreviousEntry->Next = Entry->Next;
|
||||
ListHead->Depth--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splices a singly linked list at the head of another list. The source list is reinitialized to empty.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that represents the head of the list.
|
||||
*
|
||||
* @param SpliceList
|
||||
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::SinglyList::SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN OUT PSINGLE_LIST_HEADER SpliceList)
|
||||
{
|
||||
PSINGLE_LIST_ENTRY LastEntry;
|
||||
|
||||
/* Check if the list to splice is empty */
|
||||
if(ListEmpty(SpliceList))
|
||||
{
|
||||
/* Nothing to splice, return */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the last entry of the list to splice */
|
||||
LastEntry = SpliceList->Next.Next;
|
||||
while(LastEntry->Next != NULLPTR)
|
||||
{
|
||||
/* Move to the next entry */
|
||||
LastEntry = LastEntry->Next;
|
||||
}
|
||||
|
||||
/* Splice the list at the head of destination */
|
||||
LastEntry->Next = ListHead->Next.Next;
|
||||
ListHead->Next.Next = SpliceList->Next.Next;
|
||||
|
||||
/* Update depth of the destination list */
|
||||
ListHead->Depth += SpliceList->Depth;
|
||||
|
||||
/* Reinitialize the source list to empty */
|
||||
SpliceList->Next.Next = NULLPTR;
|
||||
SpliceList->Depth = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splices a singly linked list at the tail of another list. The source list is reinitialized to empty.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to the head of the destination list.
|
||||
*
|
||||
* @param SpliceList
|
||||
* Supplies a pointer to the head of the list that will be spliced.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
RTL::SinglyList::SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
||||
IN OUT PSINGLE_LIST_HEADER SpliceList)
|
||||
{
|
||||
PSINGLE_LIST_ENTRY LastEntry;
|
||||
|
||||
/* Check if the list to splice is empty */
|
||||
if(ListEmpty(SpliceList))
|
||||
{
|
||||
/* Nothing to splice, return */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the destination list is empty */
|
||||
if(ListHead->Next.Next == NULLPTR)
|
||||
{
|
||||
/* Simply move the splice list to the destination head */
|
||||
ListHead->Next.Next = SpliceList->Next.Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find the last entry of the destination list */
|
||||
LastEntry = ListHead->Next.Next;
|
||||
while(LastEntry->Next != NULLPTR)
|
||||
{
|
||||
/* Move to the next entry */
|
||||
LastEntry = LastEntry->Next;
|
||||
}
|
||||
|
||||
/* Splice the list at the tail of destination */
|
||||
LastEntry->Next = SpliceList->Next.Next;
|
||||
}
|
||||
|
||||
/* Update depth of the destination list */
|
||||
ListHead->Depth += SpliceList->Depth;
|
||||
|
||||
/* Reinitialize the source list to empty */
|
||||
SpliceList->Next.Next = NULLPTR;
|
||||
SpliceList->Depth = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user