Add function to generate cryptographically strong random bytes for the GUID on image creation.

This commit is contained in:
2025-10-11 13:24:45 +01:00
parent e2f3323a04
commit e66b263183
3 changed files with 54 additions and 0 deletions

View File

@@ -59,5 +59,6 @@ aaru_options parse_options(const char *options);
uint64_t get_filetime_uint64();
int32_t aaruf_close_current_block(aaruformat_context *ctx);
int compare_extents(const void *a, const void *b);
void generate_random_bytes(uint8_t *buffer, size_t length);
#endif // LIBAARUFORMAT_INTERNAL_H

View File

@@ -343,6 +343,10 @@ AARU_EXPORT void AARU_CALL *aaruf_create(const char *filepath, const uint32_t me
ctx->header.creationTime = get_filetime_uint64();
ctx->header.lastWrittenTime = get_filetime_uint64();
// Generate random GUID for the image
TRACE("Generating random GUID");
generate_random_bytes(ctx->header.guid, GUID_SIZE);
ctx->readableSectorTags = (bool *)malloc(sizeof(bool) * MaxSectorTag);
if(ctx->readableSectorTags == NULL)

View File

@@ -19,6 +19,14 @@
#include <aaru.h>
#include <aaruformat.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if defined(_WIN32) || defined(_WIN64)
#include <wincrypt.h>
#include <windows.h>
#endif
/**
* @brief Converts an image data type to an Aaru media tag type.
@@ -457,3 +465,44 @@ int compare_extents(const void *a, const void *b)
if(extent_a->start > extent_b->start) return 1;
return 0;
}
/**
* @brief Generates cryptographically strong random bytes.
*
* This function fills the provided buffer with random bytes using platform-appropriate
* cryptographic random number generators. On Unix-like systems (including macOS and Linux),
* it reads from /dev/urandom. On Windows, it uses CryptGenRandom. If the platform-specific
* methods fail, it falls back to a time-seeded pseudo-random generator.
*
* @param buffer Pointer to the buffer to fill with random bytes.
* @param length Number of random bytes to generate.
*/
void generate_random_bytes(uint8_t *buffer, size_t length)
{
if(buffer == NULL || length == 0) return;
#if defined(_WIN32) || defined(_WIN64)
// Windows implementation using CryptGenRandom
HCRYPTPROV hCryptProv;
if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
CryptGenRandom(hCryptProv, (DWORD)length, buffer);
CryptReleaseContext(hCryptProv, 0);
return;
}
#else
// Unix-like systems (Linux, macOS, BSD, etc.) - use /dev/urandom
FILE *urandom = fopen("/dev/urandom", "rb");
if(urandom != NULL)
{
size_t bytes_read = fread(buffer, 1, length, urandom);
fclose(urandom);
if(bytes_read == length) return;
}
#endif
// Fallback: use time-seeded rand() if platform-specific methods fail
// This is less secure but ensures we always generate some random data
srand((unsigned int)time(NULL));
for(size_t i = 0; i < length; i++) { buffer[i] = (uint8_t)(rand() % 256); }
}