crypto: check+throw for Cryptonight v1 invalid input

If `crypto::cn_slow_hash()` is called with `variant=1` and an input length of less thab 43 bytes, it triggers a program exit.
This checks first and throws an exception instead.

Thank you to ADA Logics and the MAGIC Monero Fund for reporting this!
This commit is contained in:
jeffro256 2025-07-11 11:19:40 -05:00
parent 125622d5bd
commit 3c05f00b85
No known key found for this signature in database
GPG key ID: 6F79797A6E392442

View file

@ -30,8 +30,9 @@
#pragma once #pragma once
#include <stddef.h>
#include <iostream> #include <iostream>
#include <stddef.h>
#include <stdexcept>
#include "common/pod-class.h" #include "common/pod-class.h"
#include "generic-ops.h" #include "generic-ops.h"
@ -70,11 +71,20 @@ namespace crypto {
return h; return h;
} }
static constexpr void cn_variant1_check(const std::size_t length, const int variant)
{
// see VARIANT1_CHECK in slow-hash.c
if (variant == 1 && length < 43)
throw std::logic_error("Cryptonight variant 1 is undefined for inputs of less than 43 bytes");
}
inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
cn_variant1_check(length, variant);
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/, height); cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/, height);
} }
inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
cn_variant1_check(length, variant);
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/, height); cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/, height);
} }