hardening: add MP_ZERO_BUFFER, MP_ZERO_DIGITS
* (!) Always zero buffer before freeing if MP_NO_ZERO_ON_FREE is not defined * Add MP_NO_ZERO_ON_FREE to disable hardening * Add MP_ZERO_BUFFER, MP_ZERO_DIGITS, MP_FREE_BUFFFER, MP_FREE_DIGITS * Never use MP_FREE directly, use MP_FREE_DIGITS or MP_FREE_BUFFER * Add MP_USE_MEMSET to use memset instead of loop * Disable astyle backups which are annonying in the times of git
This commit is contained in:
parent
55e312b1c1
commit
61d9e528a4
3
astylerc
3
astylerc
@ -4,6 +4,9 @@
|
|||||||
# usage:
|
# usage:
|
||||||
# astyle --options=astylerc *.[ch]
|
# astyle --options=astylerc *.[ch]
|
||||||
|
|
||||||
|
# Do not create backup, annonying in the times of git
|
||||||
|
suffix=none
|
||||||
|
|
||||||
## Bracket Style Options
|
## Bracket Style Options
|
||||||
style=kr
|
style=kr
|
||||||
|
|
||||||
|
@ -85,9 +85,7 @@ int mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
|
|||||||
c->sign = MP_ZPOS;
|
c->sign = MP_ZPOS;
|
||||||
|
|
||||||
/* now zero to oldused */
|
/* now zero to oldused */
|
||||||
while (ix++ < oldused) {
|
MP_ZERO_DIGITS(tmpc, oldused - ix);
|
||||||
*tmpc++ = 0;
|
|
||||||
}
|
|
||||||
mp_clamp(c);
|
mp_clamp(c);
|
||||||
|
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
|
@ -29,9 +29,7 @@ int mp_and(const mp_int *a, const mp_int *b, mp_int *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* zero digits above the last from the smallest mp_int */
|
/* zero digits above the last from the smallest mp_int */
|
||||||
for (; ix < t.used; ix++) {
|
MP_ZERO_DIGITS(t.dp + ix, t.used - ix);
|
||||||
t.dp[ix] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_clamp(&t);
|
mp_clamp(&t);
|
||||||
mp_exch(c, &t);
|
mp_exch(c, &t);
|
||||||
|
@ -6,17 +6,10 @@
|
|||||||
/* clear one (frees) */
|
/* clear one (frees) */
|
||||||
void mp_clear(mp_int *a)
|
void mp_clear(mp_int *a)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* only do anything if a hasn't been freed previously */
|
/* only do anything if a hasn't been freed previously */
|
||||||
if (a->dp != NULL) {
|
if (a->dp != NULL) {
|
||||||
/* first zero the digits */
|
|
||||||
for (i = 0; i < a->used; i++) {
|
|
||||||
a->dp[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free ram */
|
/* free ram */
|
||||||
MP_FREE(a->dp, sizeof(mp_digit) * (size_t)a->alloc);
|
MP_FREE_DIGITS(a->dp, a->alloc);
|
||||||
|
|
||||||
/* reset members to make debugging easier */
|
/* reset members to make debugging easier */
|
||||||
a->dp = NULL;
|
a->dp = NULL;
|
||||||
|
@ -38,9 +38,7 @@ int mp_copy(const mp_int *a, mp_int *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* clear high digits */
|
/* clear high digits */
|
||||||
for (; n < b->used; n++) {
|
MP_ZERO_DIGITS(tmpb, b->used - n);
|
||||||
*tmpb++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy used count and sign */
|
/* copy used count and sign */
|
||||||
|
@ -40,10 +40,7 @@ int mp_div_2(const mp_int *a, mp_int *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* zero excess digits */
|
/* zero excess digits */
|
||||||
tmpb = b->dp + b->used;
|
MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
|
||||||
for (x = b->used; x < oldused; x++) {
|
|
||||||
*tmpb++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
b->sign = a->sign;
|
b->sign = a->sign;
|
||||||
mp_clamp(b);
|
mp_clamp(b);
|
||||||
|
@ -58,9 +58,7 @@ top:
|
|||||||
*tmpx1++ = mu;
|
*tmpx1++ = mu;
|
||||||
|
|
||||||
/* zero words above m */
|
/* zero words above m */
|
||||||
for (i = m + 1; i < x->used; i++) {
|
MP_ZERO_DIGITS(tmpx1, x->used - m - 1);
|
||||||
*tmpx1++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clamp, sub and return */
|
/* clamp, sub and return */
|
||||||
mp_clamp(x);
|
mp_clamp(x);
|
||||||
|
@ -19,18 +19,18 @@ int mp_fwrite(const mp_int *a, int radix, FILE *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
|
if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
|
||||||
MP_FREE(buf, len);
|
MP_FREE_BUFFER(buf, (size_t)len);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = 0; x < len; x++) {
|
for (x = 0; x < len; x++) {
|
||||||
if (fputc((int)buf[x], stream) == EOF) {
|
if (fputc((int)buf[x], stream) == EOF) {
|
||||||
MP_FREE(buf, len);
|
MP_FREE_BUFFER(buf, (size_t)len);
|
||||||
return MP_VAL;
|
return MP_VAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_FREE(buf, len);
|
MP_FREE_BUFFER(buf, (size_t)len);
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,9 +34,7 @@ int mp_grow(mp_int *a, int size)
|
|||||||
/* zero excess digits */
|
/* zero excess digits */
|
||||||
i = a->alloc;
|
i = a->alloc;
|
||||||
a->alloc = size;
|
a->alloc = size;
|
||||||
for (; i < a->alloc; i++) {
|
MP_ZERO_DIGITS(a->dp + i, a->alloc - i);
|
||||||
a->dp[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ int mp_mod_2d(const mp_int *a, int b, mp_int *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* zero digits above the last digit of the modulus */
|
/* zero digits above the last digit of the modulus */
|
||||||
for (x = (b / MP_DIGIT_BIT) + (((b % MP_DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) {
|
x = (b / MP_DIGIT_BIT) + (((b % MP_DIGIT_BIT) == 0) ? 0 : 1);
|
||||||
c->dp[x] = 0;
|
MP_ZERO_DIGITS(c->dp + x, c->used - x);
|
||||||
}
|
|
||||||
/* clear the digit that is not completely outside/inside the modulus */
|
/* clear the digit that is not completely outside/inside the modulus */
|
||||||
c->dp[b / MP_DIGIT_BIT] &=
|
c->dp[b / MP_DIGIT_BIT] &=
|
||||||
((mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT)) - (mp_digit)1;
|
((mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT)) - (mp_digit)1;
|
||||||
|
@ -55,10 +55,7 @@ int mp_mul_2(const mp_int *a, mp_int *b)
|
|||||||
/* now zero any excess digits on the destination
|
/* now zero any excess digits on the destination
|
||||||
* that we didn't write to
|
* that we didn't write to
|
||||||
*/
|
*/
|
||||||
tmpb = b->dp + b->used;
|
MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
|
||||||
for (x = b->used; x < oldused; x++) {
|
|
||||||
*tmpb++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
b->sign = a->sign;
|
b->sign = a->sign;
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
|
@ -49,9 +49,7 @@ int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c)
|
|||||||
++ix;
|
++ix;
|
||||||
|
|
||||||
/* now zero digits above the top */
|
/* now zero digits above the top */
|
||||||
while (ix++ < olduse) {
|
MP_ZERO_DIGITS(tmpc, olduse - ix);
|
||||||
*tmpc++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set used count */
|
/* set used count */
|
||||||
c->used = a->used + 1;
|
c->used = a->used + 1;
|
||||||
|
@ -114,7 +114,7 @@ static int s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_m
|
|||||||
|
|
||||||
err = MP_OKAY;
|
err = MP_OKAY;
|
||||||
error:
|
error:
|
||||||
MP_FREE(tmp, bsize);
|
MP_FREE_BUFFER(tmp, (size_t)bsize);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +67,8 @@ int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* zero excess digits */
|
/* zero excess digits */
|
||||||
while (ix++ < oldused) {
|
MP_ZERO_DIGITS(tmpc, oldused - ix);
|
||||||
*tmpc++ = 0;
|
|
||||||
}
|
|
||||||
mp_clamp(c);
|
mp_clamp(c);
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,8 @@
|
|||||||
/* set to zero */
|
/* set to zero */
|
||||||
void mp_zero(mp_int *a)
|
void mp_zero(mp_int *a)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
mp_digit *tmp;
|
|
||||||
|
|
||||||
a->sign = MP_ZPOS;
|
a->sign = MP_ZPOS;
|
||||||
a->used = 0;
|
a->used = 0;
|
||||||
|
MP_ZERO_DIGITS(a->dp, a->alloc);
|
||||||
tmp = a->dp;
|
|
||||||
for (n = 0; n < a->alloc; n++) {
|
|
||||||
*tmp++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,9 +81,7 @@ int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
|
|||||||
*tmpc++ = u;
|
*tmpc++ = u;
|
||||||
|
|
||||||
/* clear digits above oldused */
|
/* clear digits above oldused */
|
||||||
for (i = c->used; i < olduse; i++) {
|
MP_ZERO_DIGITS(tmpc, olduse - c->used);
|
||||||
*tmpc++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_clamp(c);
|
mp_clamp(c);
|
||||||
|
@ -49,8 +49,8 @@ int s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* zero the high words of W[a->used..m->used*2] */
|
/* zero the high words of W[a->used..m->used*2] */
|
||||||
for (; ix < ((n->used * 2) + 1); ix++) {
|
if (ix < ((n->used * 2) + 1)) {
|
||||||
*_W++ = 0;
|
MP_ZERO_BUFFER(_W, sizeof(mp_word) * (size_t)(((n->used * 2) + 1) - ix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,9 +142,7 @@ int s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho)
|
|||||||
/* zero oldused digits, if the input a was larger than
|
/* zero oldused digits, if the input a was larger than
|
||||||
* m->used+1 we'll have to clear the digits
|
* m->used+1 we'll have to clear the digits
|
||||||
*/
|
*/
|
||||||
for (; ix < olduse; ix++) {
|
MP_ZERO_DIGITS(tmpx, olduse - ix);
|
||||||
*tmpx++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the max used and clamp */
|
/* set the max used and clamp */
|
||||||
|
@ -81,9 +81,7 @@ int s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* clear unused digits [that existed in the old copy of c] */
|
/* clear unused digits [that existed in the old copy of c] */
|
||||||
for (; ix < olduse; ix++) {
|
MP_ZERO_DIGITS(tmpc, olduse - ix);
|
||||||
*tmpc++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mp_clamp(c);
|
mp_clamp(c);
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
|
@ -72,9 +72,7 @@ int s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int dig
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* clear unused digits [that existed in the old copy of c] */
|
/* clear unused digits [that existed in the old copy of c] */
|
||||||
for (; ix < olduse; ix++) {
|
MP_ZERO_DIGITS(tmpc, olduse - ix);
|
||||||
*tmpc++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mp_clamp(c);
|
mp_clamp(c);
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
|
@ -88,9 +88,7 @@ int s_mp_sqr_fast(const mp_int *a, mp_int *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* clear unused digits [that existed in the old copy of c] */
|
/* clear unused digits [that existed in the old copy of c] */
|
||||||
for (; ix < olduse; ix++) {
|
MP_ZERO_DIGITS(tmpb, olduse - ix);
|
||||||
*tmpb++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mp_clamp(b);
|
mp_clamp(b);
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
|
@ -60,9 +60,7 @@ int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* clear digits above used (since we may not have grown result above) */
|
/* clear digits above used (since we may not have grown result above) */
|
||||||
for (i = c->used; i < olduse; i++) {
|
MP_ZERO_DIGITS(tmpc, olduse - c->used);
|
||||||
*tmpc++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_clamp(c);
|
mp_clamp(c);
|
||||||
|
@ -10,6 +10,42 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Hardening libtommath
|
||||||
|
* --------------------
|
||||||
|
*
|
||||||
|
* By default memory is zeroed before calling
|
||||||
|
* MP_FREE to avoid leaking data. This is good
|
||||||
|
* practice in cryptographical applications.
|
||||||
|
*
|
||||||
|
* Note however that memory allocators used
|
||||||
|
* in cryptographical applications can often
|
||||||
|
* be configured by itself to clear memory,
|
||||||
|
* rendering the clearing in tommath unnecessary.
|
||||||
|
* See for example https://github.com/GrapheneOS/hardened_malloc
|
||||||
|
* and the option CONFIG_ZERO_ON_FREE.
|
||||||
|
*
|
||||||
|
* Furthermore there are applications which
|
||||||
|
* value performance more and want this
|
||||||
|
* feature to be disabled. For such applications
|
||||||
|
* define MP_NO_ZERO_ON_FREE during compilation.
|
||||||
|
*/
|
||||||
|
#ifdef MP_NO_ZERO_ON_FREE
|
||||||
|
# define MP_FREE_BUFFER(mem, size) MP_FREE((mem), (size))
|
||||||
|
# define MP_FREE_DIGITS(mem, digits) MP_FREE((mem), sizeof (mp_digit) * (digits))
|
||||||
|
#else
|
||||||
|
# define MP_FREE_BUFFER(mem, size) do { size_t fs_ = (size); void* fm_ = (mem); if (fm_) { MP_ZERO_BUFFER(fm_, fs_); MP_FREE(fm_, fs_); } } while (0)
|
||||||
|
# define MP_FREE_DIGITS(mem, digits) do { int fd_ = (digits); void* fm_ = (mem); if (fm_) { MP_ZERO_BUFFER(fm_, sizeof (mp_digit) * (size_t)fd_); MP_FREE(fm_, sizeof (mp_digit) * (size_t)fd_); } } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MP_USE_MEMSET
|
||||||
|
# include <string.h>
|
||||||
|
# define MP_ZERO_BUFFER(mem, size) memset((mem), 0, (size))
|
||||||
|
# define MP_ZERO_DIGITS(mem, digits) do { int zd_ = (digits); if (zd_ > 0) { memset((mem), 0, sizeof (mp_digit) * (size_t)zd_); } } while (0)
|
||||||
|
#else
|
||||||
|
# define MP_ZERO_BUFFER(mem, size) do { size_t zs_ = (size); char* zm_ = (char*)(mem); while (zs_-- > 0) { *zm_++ = 0; } } while (0)
|
||||||
|
# define MP_ZERO_DIGITS(mem, digits) do { int zd_ = (digits); mp_digit* zm_ = (mem); while (zd_-- > 0) { *zm_++ = 0; } } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Tunable cutoffs
|
/* Tunable cutoffs
|
||||||
* ---------------
|
* ---------------
|
||||||
*
|
*
|
||||||
@ -43,8 +79,8 @@ extern "C" {
|
|||||||
/* default to libc stuff */
|
/* default to libc stuff */
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# define MP_MALLOC(size) malloc(size)
|
# define MP_MALLOC(size) malloc(size)
|
||||||
# define MP_REALLOC(mem, oldsize, newsize) realloc(mem, newsize)
|
# define MP_REALLOC(mem, oldsize, newsize) realloc((mem), (newsize))
|
||||||
# define MP_CALLOC(nmemb, size) calloc(nmemb, size)
|
# define MP_CALLOC(nmemb, size) calloc((nmemb), (size))
|
||||||
# define MP_FREE(mem, size) free(mem)
|
# define MP_FREE(mem, size) free(mem)
|
||||||
#else
|
#else
|
||||||
/* prototypes for our heap functions */
|
/* prototypes for our heap functions */
|
||||||
|
Loading…
Reference in New Issue
Block a user