summaryrefslogtreecommitdiff
path: root/MdePkg/Library/BaseLib/ConvertGuidUuid.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdePkg/Library/BaseLib/ConvertGuidUuid.c')
-rw-r--r--MdePkg/Library/BaseLib/ConvertGuidUuid.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/MdePkg/Library/BaseLib/ConvertGuidUuid.c b/MdePkg/Library/BaseLib/ConvertGuidUuid.c
new file mode 100644
index 0000000..85a3d63
--- /dev/null
+++ b/MdePkg/Library/BaseLib/ConvertGuidUuid.c
@@ -0,0 +1,121 @@
+/** @file
+ Convert 128 bit unique identifier between GUID and UUID format.
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "BaseLibInternals.h"
+
+/*******************************************************************************
+
+ UUID (Universally Unique IDentifier), as defined in RFC4122
+ (https://datatracker.ietf.org/doc/html/rfc4122#section-4.1), is a 128-bit number
+ used to uniquely identify information in computer systems.
+
+ UUIDs contains 5 fields:
+ - time_low: 32 bits
+ - time_mid: 16 bits
+ - time_hi_and_version: 16 bits
+ - clock_seq_hi_and_reserved: 8 bits
+ - clock_seq_low: 8 bits
+ - node: 8 bits * 6
+
+ Each field encoded with the Most Significant Byte first (known as network byte
+ order, or big-endian).
+
+ GUID (Globally Unique Identifier), on the other hand, is a 128-bit number used
+ in UEFI environments, which is similar to UUID but has a different byte order
+ in memory. See https://uefi.org/specs/UEFI/2.11/Apx_A_GUID_and_Time_Formats.html
+
+ GUID also contains 5 fields:
+ - TimeLow: 32 bits
+ - TimeMid: 16 bits
+ - TimeHiAndVersion: 16 bits
+ - ClockSeqHighAndReserved: 16 bits
+ - ClockSeqLow: 8 bits
+ - Node: 8 bits * 6
+
+ TimeLow, TimeMid, TimeHighAndVersion fields in the EFI are encoded with the Least
+ Significant Byte first (also known as little-endian).
+
+ Example:
+ Consider the same string representation/registry format for MM communication v2:
+ "378daedc-f06b-4446-8314-40ab933c87a3"
+
+ In UUID format, it is represented as:
+ - Data fields:
+ - time_low: 0x37 0x8d 0xae 0xdc (0x378daedc in big-endian)
+ - time_mid: 0xf0 0x6b (0xf06b in big-endian)
+ - time_hi_and_version: 0x44 0x46 (0x4446 in big-endian)
+ - clock_seq_hi_and_reserved: 0x83
+ - clock_seq_low: 0x14
+ - node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
+ - Byte representation in memory:
+ - 37 8d ae dc f0 6b 44 46 83 14 40 ab 93 3c 87 a3
+
+ However, in GUID format, it is represented as:
+ - Data fields:
+ - TimeLow: 0xdc 0xae 0x8d 0x37 (0x378daedc in little-endian)
+ - TimeMid: 0x6b 0xf0 (0xf06b in little-endian)
+ - TimeHiAndVersion: 0x46 0x44 (0x4446 in little-endian)
+ - ClockSeqHighAndReserved: 0x83
+ - ClockSeqLow: 0x14
+ - Node: 0x00, 0xab, 0x93, 0x3c, 0x87, 0xa3
+ - Byte representation in memory:
+ - dc ae 8d 37 6b f0 46 44 83 14 40 ab 93 3c 87 a3
+
+*******************************************************************************/
+
+/**
+ This function converts a GUID in UEFI format to a UUID in RFC4122 format.
+
+ The conversion is done by swapping the byte order of the TimeLow, TimeMid, and
+ TimeHiAndVersion fields, while keeping the ClockSeq and Node fields unchanged.
+
+ @param [in] FromGuid GUID in format to be converted to UUID RFC4122 format.
+ @param [out] ToUuid Pointer to a GUID structure that will hold the converted
+ UUID in RFC4122 format.
+**/
+VOID
+EFIAPI
+ConvertGuidToUuid (
+ IN GUID *FromGuid,
+ OUT GUID *ToUuid
+ )
+{
+ ASSERT (ToUuid != NULL);
+ ASSERT (FromGuid != NULL);
+
+ CopyGuid (ToUuid, FromGuid);
+ ToUuid->Data1 = SwapBytes32 (ToUuid->Data1);
+ ToUuid->Data2 = SwapBytes16 (ToUuid->Data2);
+ ToUuid->Data3 = SwapBytes16 (ToUuid->Data3);
+}
+
+/**
+ This function converts a UUID in RFC4122 format to a GUID in UEFI format.
+
+ The conversion is done by swapping the byte order of the time_low, time_mid, and
+ time_hi_and_version fields, while keeping the ClockSeq and Node fields unchanged.
+ This function is symmetric to ConvertGuidToUuid.
+
+ @param [in] FromUuid UUID in RFC4122 format to be converted to GUID in UEFI format.
+ @param [out] ToGuid Pointer to a GUID structure that will hold the converted
+ GUID in UEFI format.
+**/
+VOID
+EFIAPI
+ConvertUuidToGuid (
+ IN GUID *FromUuid,
+ OUT GUID *ToGuid
+ )
+{
+ // The conversion is symmetric, so we can use the same function.
+ // The only difference is the order of the parameters.
+ ConvertGuidToUuid (
+ FromUuid,
+ ToGuid
+ );
+}