Uses the existing code for av_get_random_seed() to return a buffer with cryptographically secure random data, or an error if none could be generated.
Signed-off-by: James Almer <jamr...@gmail.com> --- TODO: APIChanges entry and minor version bump. Also, if a new random.h header is prefered, i can move the prototype there. libavutil/random_seed.c | 46 ++++++++++++++++++++++++++--------------- libavutil/random_seed.h | 12 +++++++++++ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c index 66dd504ef0..39fb27c5ad 100644 --- a/libavutil/random_seed.c +++ b/libavutil/random_seed.c @@ -46,20 +46,20 @@ #define TEST 0 #endif -static int read_random(uint32_t *dst, const char *file) -{ #if HAVE_UNISTD_H +static ssize_t read_random(uint8_t *dst, size_t len, const char *file) +{ int fd = avpriv_open(file, O_RDONLY); - int err = -1; + ssize_t err = -1; + if (len > SSIZE_MAX) + return -1; if (fd == -1) return -1; - err = read(fd, dst, sizeof(*dst)); + err = read(fd, dst, len); close(fd); return err; -#else - return -1; #endif } @@ -118,29 +118,41 @@ static uint32_t get_generic_seed(void) return AV_RB32(digest) + AV_RB32(digest + 16); } -uint32_t av_get_random_seed(void) +int av_random(uint8_t* buf, size_t len) { - uint32_t seed; - #if HAVE_BCRYPT BCRYPT_ALG_HANDLE algo_handle; NTSTATUS ret = BCryptOpenAlgorithmProvider(&algo_handle, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (BCRYPT_SUCCESS(ret)) { - NTSTATUS ret = BCryptGenRandom(algo_handle, (UCHAR*)&seed, sizeof(seed), 0); + NTSTATUS ret = BCryptGenRandom(algo_handle, (PUCHAR)buf, len, 0); BCryptCloseAlgorithmProvider(algo_handle, 0); if (BCRYPT_SUCCESS(ret)) - return seed; + return 0; } #endif #if HAVE_ARC4RANDOM - return arc4random(); + arc4random_buf(buf, len); + return 0; +#endif + +#if HAVE_UNISTD_H + if (read_random(buf, len, "/dev/urandom") == len) + return 0; + if (read_random(buf, len, "/dev/random") == len) + return 0; #endif - if (read_random(&seed, "/dev/urandom") == sizeof(seed)) - return seed; - if (read_random(&seed, "/dev/random") == sizeof(seed)) - return seed; - return get_generic_seed(); + return AVERROR_INVALIDDATA; +} + +uint32_t av_get_random_seed(void) +{ + uint32_t seed; + + if (av_random((uint8_t *)&seed, sizeof(seed)) < 0) + return get_generic_seed(); + + return seed; } diff --git a/libavutil/random_seed.h b/libavutil/random_seed.h index 0462a048e0..ce982bb82f 100644 --- a/libavutil/random_seed.h +++ b/libavutil/random_seed.h @@ -36,6 +36,18 @@ */ uint32_t av_get_random_seed(void); +/** + * Generate cryptographically secure random data, i.e. suitable for use as + * encryption keys and similar. + * + * @param buf buffer into which the random data will be written + * @param len size of buf in bytes + * + * @retval 0 success, and len bytes of random data was written into buf, or + * a negative AVERROR code if random data could not be generated. + */ +int av_random(uint8_t* buf, size_t len); + /** * @} */ -- 2.41.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".