1 /** @file 2 Helper functions for SecureBoot configuration module. 3 4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "SecureBootConfigImpl.h" 16 17 /** 18 Read file content into BufferPtr, the size of the allocate buffer 19 is *FileSize plus AddtionAllocateSize. 20 21 @param[in] FileHandle The file to be read. 22 @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. 23 @param[out] FileSize Size of input file 24 @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. 25 In case the buffer need to contain others besides the file content. 26 27 @retval EFI_SUCCESS The file was read into the buffer. 28 @retval EFI_INVALID_PARAMETER A parameter was invalid. 29 @retval EFI_OUT_OF_RESOURCES A memory allocation failed. 30 @retval others Unexpected error. 31 32 **/ 33 EFI_STATUS 34 ReadFileContent ( 35 IN EFI_FILE_HANDLE FileHandle, 36 IN OUT VOID **BufferPtr, 37 OUT UINTN *FileSize, 38 IN UINTN AddtionAllocateSize 39 ) 40 41 { 42 UINTN BufferSize; 43 UINT64 SourceFileSize; 44 VOID *Buffer; 45 EFI_STATUS Status; 46 47 if ((FileHandle == NULL) || (FileSize == NULL)) { 48 return EFI_INVALID_PARAMETER; 49 } 50 51 Buffer = NULL; 52 53 // 54 // Get the file size 55 // 56 Status = FileHandle->SetPosition (FileHandle, (UINT64) -1); 57 if (EFI_ERROR (Status)) { 58 goto ON_EXIT; 59 } 60 61 Status = FileHandle->GetPosition (FileHandle, &SourceFileSize); 62 if (EFI_ERROR (Status)) { 63 goto ON_EXIT; 64 } 65 66 Status = FileHandle->SetPosition (FileHandle, 0); 67 if (EFI_ERROR (Status)) { 68 goto ON_EXIT; 69 } 70 71 BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize; 72 Buffer = AllocateZeroPool(BufferSize); 73 if (Buffer == NULL) { 74 return EFI_OUT_OF_RESOURCES; 75 } 76 77 BufferSize = (UINTN) SourceFileSize; 78 *FileSize = BufferSize; 79 80 Status = FileHandle->Read (FileHandle, &BufferSize, Buffer); 81 if (EFI_ERROR (Status) || BufferSize != *FileSize) { 82 FreePool (Buffer); 83 Buffer = NULL; 84 Status = EFI_BAD_BUFFER_SIZE; 85 goto ON_EXIT; 86 } 87 88 ON_EXIT: 89 90 *BufferPtr = Buffer; 91 return Status; 92 } 93 94 /** 95 Close an open file handle. 96 97 @param[in] FileHandle The file handle to close. 98 99 **/ 100 VOID 101 CloseFile ( 102 IN EFI_FILE_HANDLE FileHandle 103 ) 104 { 105 if (FileHandle != NULL) { 106 FileHandle->Close (FileHandle); 107 } 108 } 109 110 /** 111 Convert a nonnegative integer to an octet string of a specified length. 112 113 @param[in] Integer Pointer to the nonnegative integer to be converted 114 @param[in] IntSizeInWords Length of integer buffer in words 115 @param[out] OctetString Converted octet string of the specified length 116 @param[in] OSSizeInBytes Intended length of resulting octet string in bytes 117 118 Returns: 119 120 @retval EFI_SUCCESS Data conversion successfully 121 @retval EFI_BUFFER_TOOL_SMALL Buffer is too small for output string 122 123 **/ 124 EFI_STATUS 125 EFIAPI 126 Int2OctStr ( 127 IN CONST UINTN *Integer, 128 IN UINTN IntSizeInWords, 129 OUT UINT8 *OctetString, 130 IN UINTN OSSizeInBytes 131 ) 132 { 133 CONST UINT8 *Ptr1; 134 UINT8 *Ptr2; 135 136 for (Ptr1 = (CONST UINT8 *)Integer, Ptr2 = OctetString + OSSizeInBytes - 1; 137 Ptr1 < (UINT8 *)(Integer + IntSizeInWords) && Ptr2 >= OctetString; 138 Ptr1++, Ptr2--) { 139 *Ptr2 = *Ptr1; 140 } 141 142 for (; Ptr1 < (CONST UINT8 *)(Integer + IntSizeInWords) && *Ptr1 == 0; Ptr1++); 143 144 if (Ptr1 < (CONST UINT8 *)(Integer + IntSizeInWords)) { 145 return EFI_BUFFER_TOO_SMALL; 146 } 147 148 if (Ptr2 >= OctetString) { 149 ZeroMem (OctetString, Ptr2 - OctetString + 1); 150 } 151 152 return EFI_SUCCESS; 153 } 154 155 156 157 /** 158 Convert a String to Guid Value. 159 160 @param[in] Str Specifies the String to be converted. 161 @param[in] StrLen Number of Unicode Characters of String (exclusive \0) 162 @param[out] Guid Return the result Guid value. 163 164 @retval EFI_SUCCESS The operation is finished successfully. 165 @retval EFI_NOT_FOUND Invalid string. 166 167 **/ 168 EFI_STATUS 169 StringToGuid ( 170 IN CHAR16 *Str, 171 IN UINTN StrLen, 172 OUT EFI_GUID *Guid 173 ) 174 { 175 CHAR16 *PtrBuffer; 176 CHAR16 *PtrPosition; 177 UINT16 *Buffer; 178 UINTN Data; 179 UINTN Index; 180 UINT16 Digits[3]; 181 182 Buffer = (CHAR16 *) AllocateZeroPool (sizeof (CHAR16) * (StrLen + 1)); 183 if (Buffer == NULL) { 184 return EFI_OUT_OF_RESOURCES; 185 } 186 187 StrCpyS (Buffer, (StrLen + 1), Str); 188 189 // 190 // Data1 191 // 192 PtrBuffer = Buffer; 193 PtrPosition = PtrBuffer; 194 while (*PtrBuffer != L'\0') { 195 if (*PtrBuffer == L'-') { 196 break; 197 } 198 PtrBuffer++; 199 } 200 if (*PtrBuffer == L'\0') { 201 FreePool (Buffer); 202 return EFI_NOT_FOUND; 203 } 204 205 *PtrBuffer = L'\0'; 206 Data = StrHexToUintn (PtrPosition); 207 Guid->Data1 = (UINT32)Data; 208 209 // 210 // Data2 211 // 212 PtrBuffer++; 213 PtrPosition = PtrBuffer; 214 while (*PtrBuffer != L'\0') { 215 if (*PtrBuffer == L'-') { 216 break; 217 } 218 PtrBuffer++; 219 } 220 if (*PtrBuffer == L'\0') { 221 FreePool (Buffer); 222 return EFI_NOT_FOUND; 223 } 224 *PtrBuffer = L'\0'; 225 Data = StrHexToUintn (PtrPosition); 226 Guid->Data2 = (UINT16)Data; 227 228 // 229 // Data3 230 // 231 PtrBuffer++; 232 PtrPosition = PtrBuffer; 233 while (*PtrBuffer != L'\0') { 234 if (*PtrBuffer == L'-') { 235 break; 236 } 237 PtrBuffer++; 238 } 239 if (*PtrBuffer == L'\0') { 240 FreePool (Buffer); 241 return EFI_NOT_FOUND; 242 } 243 *PtrBuffer = L'\0'; 244 Data = StrHexToUintn (PtrPosition); 245 Guid->Data3 = (UINT16)Data; 246 247 // 248 // Data4[0..1] 249 // 250 for ( Index = 0 ; Index < 2 ; Index++) { 251 PtrBuffer++; 252 if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) { 253 FreePool (Buffer); 254 return EFI_NOT_FOUND; 255 } 256 Digits[0] = *PtrBuffer; 257 PtrBuffer++; 258 Digits[1] = *PtrBuffer; 259 Digits[2] = L'\0'; 260 Data = StrHexToUintn (Digits); 261 Guid->Data4[Index] = (UINT8)Data; 262 } 263 264 // 265 // skip the '-' 266 // 267 PtrBuffer++; 268 if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) { 269 return EFI_NOT_FOUND; 270 } 271 272 // 273 // Data4[2..7] 274 // 275 for ( ; Index < 8; Index++) { 276 PtrBuffer++; 277 if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) { 278 FreePool (Buffer); 279 return EFI_NOT_FOUND; 280 } 281 Digits[0] = *PtrBuffer; 282 PtrBuffer++; 283 Digits[1] = *PtrBuffer; 284 Digits[2] = L'\0'; 285 Data = StrHexToUintn (Digits); 286 Guid->Data4[Index] = (UINT8)Data; 287 } 288 289 FreePool (Buffer); 290 291 return EFI_SUCCESS; 292 } 293 294 /** 295 Worker function that prints an EFI_GUID into specified Buffer. 296 297 @param[in] Guid Pointer to GUID to print. 298 @param[in] Buffer Buffer to print Guid into. 299 @param[in] BufferSize Size of Buffer. 300 301 @retval Number of characters printed. 302 303 **/ 304 UINTN 305 GuidToString ( 306 IN EFI_GUID *Guid, 307 IN CHAR16 *Buffer, 308 IN UINTN BufferSize 309 ) 310 { 311 UINTN Size; 312 313 Size = UnicodeSPrint ( 314 Buffer, 315 BufferSize, 316 L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 317 (UINTN)Guid->Data1, 318 (UINTN)Guid->Data2, 319 (UINTN)Guid->Data3, 320 (UINTN)Guid->Data4[0], 321 (UINTN)Guid->Data4[1], 322 (UINTN)Guid->Data4[2], 323 (UINTN)Guid->Data4[3], 324 (UINTN)Guid->Data4[4], 325 (UINTN)Guid->Data4[5], 326 (UINTN)Guid->Data4[6], 327 (UINTN)Guid->Data4[7] 328 ); 329 330 // 331 // SPrint will null terminate the string. The -1 skips the null 332 // 333 return Size - 1; 334 } 335