X-Git-Url: http://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=gosthash2012.c;h=bbe7dcbf83d1cb8932bf24d34b10c5f9540e04dd;hb=refs%2Fheads%2Fgost_provider;hp=f9b8f233aeff3bb9b0ef7d989290e12f9aac6949;hpb=57d07eb0dc22bee10aebb0bd37cbdf2258413564;p=openssl-gost%2Fengine.git diff --git a/gosthash2012.c b/gosthash2012.c index f9b8f23..bbe7dcb 100644 --- a/gosthash2012.c +++ b/gosthash2012.c @@ -60,18 +60,33 @@ static INLINE void add512(const union uint512_u *x, { #ifndef __GOST3411_BIG_ENDIAN__ unsigned int CF, OF; + unsigned long long tmp; unsigned int i; CF = 0; - for (i = 0; i < 8; i++) { - r->QWORD[i] = x->QWORD[i] + y->QWORD[i]; - if (r->QWORD[i] < y->QWORD[i] || r->QWORD[i] < x->QWORD[i]) + for (i = 0; i < 8; i++) + { + /* Detecting integer overflow condition for three numbers + * in a portable way is tricky a little. */ + + /* Step 1: numbers cause overflow */ + tmp = x->QWORD[i] + y->QWORD[i]; + + /* Compare with any of two summands, no need to check both */ + if (tmp < x->QWORD[i]) OF = 1; else OF = 0; - r->QWORD[i] += CF; + /* Step 2: carry bit causes overflow */ + tmp += CF; + + if (CF > 0 && tmp == 0) + OF = 1; + CF = OF; + + r->QWORD[i] = tmp; } #else const unsigned char *xp, *yp; @@ -142,10 +157,13 @@ static void g(union uint512_u *h, const union uint512_u *N, static INLINE void stage2(gost2012_hash_ctx * CTX, const unsigned char *data) { - g(&(CTX->h), &(CTX->N), data); + union uint512_u m; + + memcpy(&m, data, sizeof(m)); + g(&(CTX->h), &(CTX->N), (const unsigned char *)&m); add512(&(CTX->N), &buffer512, &(CTX->N)); - add512(&(CTX->Sigma), (const union uint512_u *)data, &(CTX->Sigma)); + add512(&(CTX->Sigma), &m, &(CTX->Sigma)); } static INLINE void stage3(gost2012_hash_ctx * CTX)