1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-20 05:18:08 +00:00

refactor(crypto): adapt ripemd160 implementation

This commit is contained in:
Ondřej Vejpustek 2024-09-01 19:04:36 +02:00
parent 3167684d08
commit fb471a96f2
3 changed files with 48 additions and 36 deletions

View File

@ -32,7 +32,7 @@
/// digest_size: int /// digest_size: int
typedef struct _mp_obj_Ripemd160_t { typedef struct _mp_obj_Ripemd160_t {
mp_obj_base_t base; mp_obj_base_t base;
RIPEMD160_CTX ctx; ripemd160_state ctx;
} mp_obj_Ripemd160_t; } mp_obj_Ripemd160_t;
STATIC mp_obj_t mod_trezorcrypto_Ripemd160_update(mp_obj_t self, mp_obj_t data); STATIC mp_obj_t mod_trezorcrypto_Ripemd160_update(mp_obj_t self, mp_obj_t data);
@ -47,7 +47,7 @@ STATIC mp_obj_t mod_trezorcrypto_Ripemd160_make_new(const mp_obj_type_t *type,
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Ripemd160_t *o = m_new_obj_with_finaliser(mp_obj_Ripemd160_t); mp_obj_Ripemd160_t *o = m_new_obj_with_finaliser(mp_obj_Ripemd160_t);
o->base.type = type; o->base.type = type;
ripemd160_Init(&(o->ctx)); ripemd160_init(&(o->ctx));
// constructor called with bytes/str as first parameter // constructor called with bytes/str as first parameter
if (n_args == 1) { if (n_args == 1) {
mod_trezorcrypto_Ripemd160_update(MP_OBJ_FROM_PTR(o), args[0]); mod_trezorcrypto_Ripemd160_update(MP_OBJ_FROM_PTR(o), args[0]);
@ -65,7 +65,7 @@ STATIC mp_obj_t mod_trezorcrypto_Ripemd160_update(mp_obj_t self,
mp_buffer_info_t msg = {0}; mp_buffer_info_t msg = {0};
mp_get_buffer_raise(data, &msg, MP_BUFFER_READ); mp_get_buffer_raise(data, &msg, MP_BUFFER_READ);
if (msg.len > 0) { if (msg.len > 0) {
ripemd160_Update(&(o->ctx), msg.buf, msg.len); ripemd160_process(&(o->ctx), msg.buf, msg.len);
} }
return mp_const_none; return mp_const_none;
} }
@ -80,10 +80,10 @@ STATIC mp_obj_t mod_trezorcrypto_Ripemd160_digest(mp_obj_t self) {
mp_obj_Ripemd160_t *o = MP_OBJ_TO_PTR(self); mp_obj_Ripemd160_t *o = MP_OBJ_TO_PTR(self);
vstr_t hash = {0}; vstr_t hash = {0};
vstr_init_len(&hash, RIPEMD160_DIGEST_LENGTH); vstr_init_len(&hash, RIPEMD160_DIGEST_LENGTH);
RIPEMD160_CTX ctx = {0}; ripemd160_state ctx = {0};
memcpy(&ctx, &(o->ctx), sizeof(RIPEMD160_CTX)); memcpy(&ctx, &(o->ctx), sizeof(ripemd160_state));
ripemd160_Final(&ctx, (uint8_t *)hash.buf); ripemd160_done(&ctx, (uint8_t *)hash.buf);
memzero(&ctx, sizeof(RIPEMD160_CTX)); memzero(&ctx, sizeof(ripemd160_state));
return mp_obj_new_str_from_vstr(&mp_type_bytes, &hash); return mp_obj_new_str_from_vstr(&mp_type_bytes, &hash);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160_digest_obj, STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160_digest_obj,
@ -91,7 +91,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160_digest_obj,
STATIC mp_obj_t mod_trezorcrypto_Ripemd160___del__(mp_obj_t self) { STATIC mp_obj_t mod_trezorcrypto_Ripemd160___del__(mp_obj_t self) {
mp_obj_Ripemd160_t *o = MP_OBJ_TO_PTR(self); mp_obj_Ripemd160_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(RIPEMD160_CTX)); memzero(&(o->ctx), sizeof(ripemd160_state));
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160___del___obj, STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160___del___obj,

View File

@ -1,9 +1,8 @@
#define _RIPEMD160_C_ 1
#include "ripemd160.h" #include "ripemd160.h"
#include <assert.h> #include <assert.h>
#include "memzero.h"
#define NDEBUG // Downlaoded from https://github.com/sipa/Coin25519/blob/master/src/crypto/ripemd160.c
// adapted by Pieter Wuille in 2012; all changes are in the public domain // adapted by Pieter Wuille in 2012; all changes are in the public domain
@ -56,8 +55,7 @@
#include <string.h> #include <string.h>
#define RIPEMD160_DIGEST_SIZE 20 #define RIPEMD160_DIGEST_SIZE RIPEMD160_DIGEST_LENGTH
#define BLOCK_SIZE 64
/* cyclic left-shift the 32-bit word n left by s bits */ /* cyclic left-shift the 32-bit word n left by s bits */
#define ROL(s, n) (((n) << (s)) | ((n) >> (32-(s)))) #define ROL(s, n) (((n) << (s)) | ((n) >> (32-(s))))
@ -155,9 +153,10 @@ void ripemd160_init(ripemd160_state *self)
self->bufpos = 0; self->bufpos = 0;
} }
#ifdef PCT_BIG_ENDIAN
static inline void byteswap32(uint32_t *v) static inline void byteswap32(uint32_t *v)
{ {
union { uint32_t w; uint8_t b[4]; } x, y; union { uint32_t w; uint8_t b[4]; } x = {0}, y = {0};
x.w = *v; x.w = *v;
y.b[0] = x.b[3]; y.b[0] = x.b[3];
@ -172,7 +171,7 @@ static inline void byteswap32(uint32_t *v)
static inline void byteswap_digest(uint32_t *p) static inline void byteswap_digest(uint32_t *p)
{ {
unsigned int i; unsigned int i = 0;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
byteswap32(p++); byteswap32(p++);
@ -181,14 +180,15 @@ static inline void byteswap_digest(uint32_t *p)
byteswap32(p++); byteswap32(p++);
} }
} }
#endif
/* The RIPEMD160 compression function. Operates on self->buf */ /* The RIPEMD160 compression function. Operates on self->buf */
static void ripemd160_compress(ripemd160_state *self) static void ripemd160_compress(ripemd160_state *self)
{ {
uint8_t w, round; uint8_t w = 0, round = 0;
uint32_t T; uint32_t T = 0;
uint32_t AL, BL, CL, DL, EL; /* left line */ uint32_t AL = 0, BL = 0, CL = 0, DL = 0, EL = 0; /* left line */
uint32_t AR, BR, CR, DR, ER; /* right line */ uint32_t AR = 0, BR = 0, CR = 0, DR = 0, ER = 0; /* right line */
/* Sanity check */ /* Sanity check */
assert(self->bufpos == 64); assert(self->bufpos == 64);
@ -269,17 +269,27 @@ static void ripemd160_compress(ripemd160_state *self)
self->h[0] = T; self->h[0] = T;
/* Clear the buffer and wipe the temporary variables */ /* Clear the buffer and wipe the temporary variables */
T = AL = BL = CL = DL = EL = AR = BR = CR = DR = ER = 0; memzero(&self->buf, sizeof(self->buf));
memset(&self->buf, 0, sizeof(self->buf)); memzero(&T, sizeof(T));
memzero(&AL, sizeof(AL));
memzero(&BL, sizeof(BL));
memzero(&CL, sizeof(CL));
memzero(&DL, sizeof(DL));
memzero(&EL, sizeof(EL));
memzero(&AR, sizeof(AR));
memzero(&BR, sizeof(BR));
memzero(&CR, sizeof(CR));
memzero(&DR, sizeof(DR));
memzero(&ER, sizeof(ER));
self->bufpos = 0; self->bufpos = 0;
} }
void ripemd160_process(ripemd160_state *self, const unsigned char *p, unsigned long length) void ripemd160_process(ripemd160_state * self, const uint8_t *p, size_t length)
{ {
unsigned long bytes_needed; unsigned long bytes_needed = 0;
/* Some assertions */ /* Some assertions */
assert(p != NULL && length >= 0); assert(p != NULL);
/* We never leave a full buffer */ /* We never leave a full buffer */
assert(self->bufpos < 64); assert(self->bufpos < 64);
@ -309,7 +319,7 @@ void ripemd160_process(ripemd160_state *self, const unsigned char *p, unsigned l
} }
} }
void ripemd160_done(ripemd160_state *self, unsigned char *out) void ripemd160_done(ripemd160_state * self, uint8_t out[RIPEMD160_DIGEST_LENGTH])
{ {
/* Append the padding */ /* Append the padding */
self->buf.b[self->bufpos++] = 0x80; self->buf.b[self->bufpos++] = 0x80;
@ -334,11 +344,12 @@ void ripemd160_done(ripemd160_state *self, unsigned char *out)
byteswap_digest(self->h); byteswap_digest(self->h);
#endif #endif
memcpy(out, &self->h, RIPEMD160_DIGEST_SIZE); memcpy(out, &self->h, RIPEMD160_DIGEST_SIZE);
memzero(self, sizeof(ripemd160_state));
} }
void ripemd160(const void* in, unsigned long length, void* out) void ripemd160(const uint8_t *in, size_t length, uint8_t out[RIPEMD160_DIGEST_LENGTH])
{ {
ripemd160_state md; ripemd160_state md = {0};
ripemd160_init(&md); ripemd160_init(&md);
ripemd160_process(&md, in, length); ripemd160_process(&md, in, length);
ripemd160_done(&md, out); ripemd160_done(&md, out);

View File

@ -1,7 +1,11 @@
#ifndef _RIPEMD160_H_ #ifndef __RIPEMD160_H__
#define _RIPEMD160_H_ #define __RIPEMD160_H__
#include <stdint.h> #include <stdint.h>
#include <stddef.h>
#define RIPEMD160_BLOCK_LENGTH 64
#define RIPEMD160_DIGEST_LENGTH 20
typedef struct { typedef struct {
uint64_t length; uint64_t length;
@ -13,11 +17,8 @@ typedef struct {
uint8_t bufpos; uint8_t bufpos;
} ripemd160_state; } ripemd160_state;
#ifndef _RIPEMD160_C_ void ripemd160_init(ripemd160_state * self);
void ripemd160_init(ripemd160_state * md); void ripemd160_process(ripemd160_state * self, const uint8_t *in, size_t length);
void ripemd160_process(ripemd160_state * md, const void *in, unsigned long inlen); void ripemd160_done(ripemd160_state * self, uint8_t out[RIPEMD160_DIGEST_LENGTH]);
void ripemd160_done(ripemd160_state * md, void *out); void ripemd160(const uint8_t *in, size_t length, uint8_t out[RIPEMD160_DIGEST_LENGTH]);
void ripemd160(const void *in, unsigned long inlen, void *out);
#endif
#endif #endif