Mimi, On Fri, Jun 21, 2019 at 09:03:56AM -0400, Mimi Zohar wrote: > On Fri, 2019-06-21 at 15:28 +0300, Vitaly Chikunov wrote: > > On Fri, Jun 21, 2019 at 07:27:30AM -0400, Mimi Zohar wrote: > > > On Fri, 2019-06-21 at 14:22 +0300, Vitaly Chikunov wrote: > > > > On Fri, Jun 21, 2019 at 07:08:12AM -0400, Mimi Zohar wrote: > > > > > On Fri, 2019-06-21 at 09:59 +0300, Vitaly Chikunov wrote: > > > > > > On Thu, Jun 20, 2019 at 05:42:18PM -0400, Mimi Zohar wrote: > > > > > > > On Tue, 2019-06-18 at 16:56 +0300, Vitaly Chikunov wrote: > > > > > > > > Fix off-by-one error of the output buffer passed to sign_hash(). > > > > > > > > > > > > > > > > Signed-off-by: Vitaly Chikunov <vt@xxxxxxxxxxxx> > > > > > > > > --- > > > > > > > > src/evmctl.c | 4 ++-- > > > > > > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > > > > > > > > > > > diff --git a/src/evmctl.c b/src/evmctl.c > > > > > > > > index 15a7226..03f41fe 100644 > > > > > > > > --- a/src/evmctl.c > > > > > > > > +++ b/src/evmctl.c > > > > > > > > @@ -510,7 +510,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash) > > > > > > > > static int sign_evm(const char *file, const char *key) > > > > > > > > { > > > > > > > > unsigned char hash[MAX_DIGEST_SIZE]; > > > > > > > > - unsigned char sig[MAX_SIGNATURE_SIZE]; > > > > > > > > + unsigned char sig[MAX_SIGNATURE_SIZE + 1]; > > > > > > > > int len, err; > > > > > > > > > > > > > > > > len = calc_evm_hash(file, hash); > > > > > > > > @@ -519,7 +519,7 @@ static int sign_evm(const char *file, const char *key) > > > > > > > > return len; > > > > > > > > > > > > > > > > len = sign_hash(params.hash_algo, hash, len, key, NULL, sig + 1); > > > > > > > > - assert(len < sizeof(sig)); > > > > > > > > + assert(len <= MAX_SIGNATURE_SIZE); > > > > > > > > if (len <= 1) > > > > > > > > return len; > > > > > > > > > > > > > > > > > > > > > > A similar problem occurs in sign_ima. Without these changes > > > > > > > sign_hash() succeeds, returning a length of 520 for > > > > > > > sha256/streebog256. > > > > > > > > > > > > I will add it. Also, I found more similar errors and will fix them together. > > > > > > > > > > The first byte of sig is reserved for the type of signature. The > > > > > remaining buffer is for the signature itself. The existing > > > > > "assert(len < sizeof(sig))" is therefore correct. The sig size being > > > > > returned is less than 1023, so why is this change needed? > > > > > > > > Well, it looked more straightforward to check explicit > > > > MAX_SIGNATURE_SIZE instead of relying on that '<' accounts for > > > > that additional byte. > > > > > > > > Main fix is of course this: > > > > > > > > > > > > - unsigned char sig[MAX_SIGNATURE_SIZE]; > > > > > > > > + unsigned char sig[MAX_SIGNATURE_SIZE + 1]; > > > > > > That is the question. Why does the buffer need to be > > > "MAX_SIGNATURE_SIZE + 1", making it 1025 bytes? MAX_SIGNATURE_SIZE - > > > 1 is large enough for the signature. > > > > Because maximum signature size is supposed to be MAX_SIGNATURE_SIZE, > > isn't it? Why in reality it should be some other value? > > No, I think it was chosen as an upper bound, simply used for buffer > bounds checking. I wouldn't make sig 1025. If you want to make > MAX_SIGNATuRE_SIZE 1023 and keep the + 1, that would be fine. I will rework these 'fixes' with my new understanding. > > That give me idea to add check if a generated signature will fit into > > `sig` (assuming it's of MAX_SIGNATURE_SIZE) in sign_hash_v2() before we > > call EVP_PKEY_sign(). > > Yes, a call to EVP_PKEY_sign(), without providing the "sig", will > return the length. evmctl can be called recursively (-r). I would > hope that EVP_PKEY_sign() would check the buffer size before > calculating the sig. If it does, then checking is duplication. I'm a > bit concerned about the performance impact of checking the sig size > each time. You are right, EVP_PKEY_sign() is already checking the buffer size. So, proposed check would be redundant. Thanks,