mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	ku: UUID v5 generation
This commit is contained in:
		
							
								
								
									
										134
									
								
								src/ku/uuid5.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/ku/uuid5.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| /** | ||||
|  * @file dll/uuid5.c | ||||
|  * | ||||
|  * @copyright 2015-2019 Bill Zissimopoulos | ||||
|  */ | ||||
| /* | ||||
|  * This file is part of WinFsp. | ||||
|  * | ||||
|  * You can redistribute it and/or modify it under the terms of the GNU | ||||
|  * General Public License version 3 as published by the Free Software | ||||
|  * Foundation. | ||||
|  * | ||||
|  * Licensees holding a valid commercial license may use this software | ||||
|  * in accordance with the commercial license agreement provided in | ||||
|  * conjunction with the software.  The terms and conditions of any such | ||||
|  * commercial license agreement shall govern, supersede, and render | ||||
|  * ineffective any application of the GPLv3 license to this software, | ||||
|  * notwithstanding of any reference thereto in the software or | ||||
|  * associated repository. | ||||
|  */ | ||||
|  | ||||
| #include <ku/library.h> | ||||
| #include <bcrypt.h> | ||||
|  | ||||
| /* | ||||
|  * This module is used to create UUID v5 identifiers. UUID v5 identifiers | ||||
|  * are effectively SHA1 hashes that are modified to fit within the UUID | ||||
|  * format. The resulting identifiers use version 5 and variant 2. The hash | ||||
|  * is taken over the concatenation of a namespace ID and a name; the namespace | ||||
|  * ID is another UUID and the name can be any string of bytes ("octets"). | ||||
|  * | ||||
|  * For details see RFC 4122: https://tools.ietf.org/html/rfc4122 | ||||
|  */ | ||||
|  | ||||
| NTSTATUS FspUuid5Make(const UUID *Namespace, const VOID *Buffer, ULONG Size, UUID *Uuid) | ||||
| { | ||||
|     BCRYPT_ALG_HANDLE ProvHandle = 0; | ||||
|     BCRYPT_HASH_HANDLE HashHandle = 0; | ||||
|     UINT8 Temp[20]; | ||||
|     NTSTATUS Result; | ||||
|  | ||||
|     /* | ||||
|      * Windows UUID's are encoded in little-endian format. RFC 4122 specifies that for | ||||
|      * UUID v5 computation, UUID's must be converted to/from big-endian. | ||||
|      * | ||||
|      * Note that Windows is always little-endian: | ||||
|      * https://community.osr.com/discussion/comment/146810/#Comment_146810 | ||||
|      */ | ||||
|  | ||||
|     /* copy Namespace to local buffer in network byte order (big-endian) */ | ||||
|     Temp[ 0] = ((PUINT8)Namespace)[ 3]; | ||||
|     Temp[ 1] = ((PUINT8)Namespace)[ 2]; | ||||
|     Temp[ 2] = ((PUINT8)Namespace)[ 1]; | ||||
|     Temp[ 3] = ((PUINT8)Namespace)[ 0]; | ||||
|     Temp[ 4] = ((PUINT8)Namespace)[ 5]; | ||||
|     Temp[ 5] = ((PUINT8)Namespace)[ 4]; | ||||
|     Temp[ 6] = ((PUINT8)Namespace)[ 7]; | ||||
|     Temp[ 7] = ((PUINT8)Namespace)[ 6]; | ||||
|     Temp[ 8] = ((PUINT8)Namespace)[ 8]; | ||||
|     Temp[ 9] = ((PUINT8)Namespace)[ 9]; | ||||
|     Temp[10] = ((PUINT8)Namespace)[10]; | ||||
|     Temp[11] = ((PUINT8)Namespace)[11]; | ||||
|     Temp[12] = ((PUINT8)Namespace)[12]; | ||||
|     Temp[13] = ((PUINT8)Namespace)[13]; | ||||
|     Temp[14] = ((PUINT8)Namespace)[14]; | ||||
|     Temp[15] = ((PUINT8)Namespace)[15]; | ||||
|  | ||||
|     /* | ||||
|      * Unfortunately we cannot reuse the hashing object, because BCRYPT_HASH_REUSABLE_FLAG | ||||
|      * is available in Windows 8 and later. (WinFsp currently supports Windows 7 or later). | ||||
|      */ | ||||
|  | ||||
|     Result = BCryptOpenAlgorithmProvider(&ProvHandle, BCRYPT_SHA1_ALGORITHM, 0, 0); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         goto exit; | ||||
|  | ||||
|     Result = BCryptCreateHash(ProvHandle, &HashHandle, 0, 0, 0, 0, 0); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         goto exit; | ||||
|  | ||||
|     Result = BCryptHashData(HashHandle, (PVOID)Temp, 16, 0); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         goto exit; | ||||
|  | ||||
|     Result = BCryptHashData(HashHandle, (PVOID)Buffer, Size, 0); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         goto exit; | ||||
|  | ||||
|     Result = BCryptFinishHash(HashHandle, Temp, 20, 0); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         goto exit; | ||||
|  | ||||
|     /* copy local buffer to Uuid in host byte order (little-endian) */ | ||||
|     ((PUINT8)Uuid)[ 0] = Temp[ 3]; | ||||
|     ((PUINT8)Uuid)[ 1] = Temp[ 2]; | ||||
|     ((PUINT8)Uuid)[ 2] = Temp[ 1]; | ||||
|     ((PUINT8)Uuid)[ 3] = Temp[ 0]; | ||||
|     ((PUINT8)Uuid)[ 4] = Temp[ 5]; | ||||
|     ((PUINT8)Uuid)[ 5] = Temp[ 4]; | ||||
|     ((PUINT8)Uuid)[ 6] = Temp[ 7]; | ||||
|     ((PUINT8)Uuid)[ 7] = Temp[ 6]; | ||||
|     ((PUINT8)Uuid)[ 8] = Temp[ 8]; | ||||
|     ((PUINT8)Uuid)[ 9] = Temp[ 9]; | ||||
|     ((PUINT8)Uuid)[10] = Temp[10]; | ||||
|     ((PUINT8)Uuid)[11] = Temp[11]; | ||||
|     ((PUINT8)Uuid)[12] = Temp[12]; | ||||
|     ((PUINT8)Uuid)[13] = Temp[13]; | ||||
|     ((PUINT8)Uuid)[14] = Temp[14]; | ||||
|     ((PUINT8)Uuid)[15] = Temp[15]; | ||||
|  | ||||
|     /* [RFC 4122 Section 4.3] | ||||
|      * Set the four most significant bits (bits 12 through 15) of the | ||||
|      * time_hi_and_version field to the appropriate 4-bit version number | ||||
|      * from Section 4.1.3. | ||||
|      */ | ||||
|     Uuid->Data3 = (5 << 12) | (Uuid->Data3 & 0x0fff); | ||||
|  | ||||
|     /* [RFC 4122 Section 4.3] | ||||
|      * Set the two most significant bits (bits 6 and 7) of the | ||||
|      * clock_seq_hi_and_reserved to zero and one, respectively. | ||||
|      */ | ||||
|     Uuid->Data4[0] = (2 << 6) | (Uuid->Data4[0] & 0x3f); | ||||
|  | ||||
|     Result = STATUS_SUCCESS; | ||||
|  | ||||
| exit: | ||||
|     if (0 != HashHandle) | ||||
|         BCryptDestroyHash(HashHandle); | ||||
|  | ||||
|     if (0 != ProvHandle) | ||||
|         BCryptCloseAlgorithmProvider(ProvHandle, 0); | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
| @@ -493,6 +493,9 @@ NTSTATUS FspFileNameInExpression( | ||||
|     PWCH UpcaseTable, | ||||
|     PBOOLEAN PResult); | ||||
|  | ||||
| /* UUID5 creation (ku) */ | ||||
| NTSTATUS FspUuid5Make(const UUID *Namespace, const VOID *Buffer, ULONG Size, UUID *Uuid); | ||||
|  | ||||
| /* utility */ | ||||
| PVOID FspAllocatePoolMustSucceed(POOL_TYPE PoolType, SIZE_T Size, ULONG Tag); | ||||
| PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user