X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=ext%2Fsolv_pgpvrfy.c;h=9bc256ca9a46b5f80817d29c6d8e4ecfa0bb6a68;hb=3ef3b1fc2683e955702472e838ff02bf2f68954a;hp=a4c819bf07306357296af07e242ef0ddbd98d0a9;hpb=3e5c879f1b770ad664b45f4eb73d254b5188ceee;p=platform%2Fupstream%2Flibsolv.git diff --git a/ext/solv_pgpvrfy.c b/ext/solv_pgpvrfy.c index a4c819b..9bc256c 100644 --- a/ext/solv_pgpvrfy.c +++ b/ext/solv_pgpvrfy.c @@ -17,6 +17,7 @@ typedef unsigned int mp_t; typedef unsigned long long mp2_t; #define MP_T_BYTES 4 + #define MP_T_BITS (MP_T_BYTES * 8) static inline void @@ -31,12 +32,30 @@ mpnew(int len) return solv_calloc(len, MP_T_BYTES); } -/* target[len] = x, target = target % mod */ +static inline void +mpcpy(int len, mp_t *target, mp_t *source) +{ + memcpy(target, source, len * MP_T_BYTES); +} + +#if 0 +static void mpdump(int l, mp_t *a, char *s) +{ + int i; + if (s) + fprintf(stderr, "%s", s); + for (i = l - 1; i >= 0; i--) + fprintf(stderr, "%0*x", MP_T_BYTES * 2, a[i]); + fprintf(stderr, "\n"); +} +#endif + +/* target[len] = x, target = target % mod + * assumes that target < (mod << MP_T_BITS)! */ static void mpdomod(int len, mp_t *target, mp2_t x, mp_t *mod) { int i, j; - /* assumes that x does not overflow, i.e. target is not much bigger than mod! */ for (i = len - 1; i >= 0; i--) { x = (x << MP_T_BITS) | target[i]; @@ -51,6 +70,8 @@ mpdomod(int len, mp_t *target, mp2_t x, mp_t *mod) /* reduce */ mp2_t z = x / ((mp2_t)mod[i] + 1); mp2_t n = 0; + if ((z >> MP_T_BITS) != 0) + z = (mp2_t)1 << MP_T_BITS; /* just in case... */ for (j = 0; j < i; j++) { mp_t n2; @@ -102,7 +123,7 @@ mpmult_add_int(int len, mp_t *target, mp_t *src, mp2_t m, mp_t *mod) mpdomod(len, target, x, mod); } -/* target = target * 2^MP_T_BITS */ +/* target = target << MP_T_BITS */ static void mpshift(int len, mp_t *target, mp_t *mod) { @@ -118,50 +139,48 @@ mpshift(int len, mp_t *target, mp_t *mod) /* target += m1 * m2 */ static void -mpmult_add(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *mod) +mpmult_add(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *tmp, mp_t *mod) { int i, j; - mp_t *t; for (j = m2len - 1; j >= 0; j--) if (m2[j]) break; if (j < 0) return; - t = mpnew(len); - memcpy(t, m1, len * MP_T_BYTES); + mpcpy(len, tmp, m1); for (i = 0; i < j; i++) { if (m2[i]) - mpmult_add_int(len, target, t, m2[i], mod); - mpshift(len, t, mod); + mpmult_add_int(len, target, tmp, m2[i], mod); + mpshift(len, tmp, mod); } if (m2[i]) - mpmult_add_int(len, target, t, m2[i], mod); - free(t); + mpmult_add_int(len, target, tmp, m2[i], mod); } /* target = target * m */ static void -mpmult_inplace(int len, mp_t *target, mp_t *m, mp_t *tmp, mp_t *mod) +mpmult_inplace(int len, mp_t *target, mp_t *m, mp_t *tmp1, mp_t *tmp2, mp_t *mod) { - mpzero(len, tmp); - mpmult_add(len, tmp, target, len, m, mod); - memcpy(target, tmp, len * MP_T_BYTES); + mpzero(len, tmp1); + mpmult_add(len, tmp1, target, len, m, tmp2, mod); + mpcpy(len, target, tmp1); } -/* target = target ^ (16 + e) */ +/* target = target ^ 16 * b ^ e */ static void mppow_int(int len, mp_t *target, mp_t *t, mp_t *mod, int e) { - mpmult_inplace(len, target, target, t, mod); - mpmult_inplace(len, target, target, t, mod); - mpmult_inplace(len, target, target, t, mod); - mpmult_inplace(len, target, target, t, mod); + mp_t *t2 = t + len * 16; + mpmult_inplace(len, target, target, t, t2, mod); + mpmult_inplace(len, target, target, t, t2, mod); + mpmult_inplace(len, target, target, t, t2, mod); + mpmult_inplace(len, target, target, t, t2, mod); if (e) - mpmult_inplace(len, target, t + len * e, t, mod); + mpmult_inplace(len, target, t + len * e, t, t2, mod); } -/* target = b ^ e */ +/* target = b ^ e (b has to be < mod) */ static void mppow(int len, mp_t *target, mp_t *b, int elen, mp_t *e, mp_t *mod) { @@ -174,10 +193,10 @@ mppow(int len, mp_t *target, mp_t *b, int elen, mp_t *e, mp_t *mod) break; if (i < 0) return; - t = mpnew(len * 16); - memcpy(t + len, b, len * MP_T_BYTES); + t = mpnew(len * 17); + mpcpy(len, t + len, b); for (j = 2; j < 16; j++) - mpmult_add(len, t + len * j, b, len, t + len * j - len, mod); + mpmult_add(len, t + len * j, b, len, t + len * j - len, t + len * 16, mod); for (; i >= 0; i--) { #if MP_T_BYTES == 4 @@ -197,6 +216,16 @@ mppow(int len, mp_t *target, mp_t *b, int elen, mp_t *e, mp_t *mod) free(t); } +/* target = m1 * m2 (m1 has to be < mod) */ +static void +mpmult(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *mod) +{ + mp_t *tmp = mpnew(len); + mpzero(len, target); + mpmult_add(len, target, m1, m2len, m2, tmp, mod); + free(tmp); +} + static int mpisless(int len, mp_t *a, mp_t *b) { @@ -230,18 +259,6 @@ mpdec(int len, mp_t *a) a[i] = -(mp_t)1; } -#if 0 -static void mpdump(int l, mp_t *a, char *s) -{ - int i; - if (s) - fprintf(stderr, "%s", s); - for (i = l - 1; i >= 0; i--) - fprintf(stderr, "%08x", a[i]); - fprintf(stderr, "\n"); -} -#endif - static int mpdsa(int pl, mp_t *p, int ql, mp_t *q, mp_t *g, mp_t *y, mp_t *r, mp_t *s, int hl, mp_t *h) { @@ -264,30 +281,28 @@ mpdsa(int pl, mp_t *p, int ql, mp_t *q, mp_t *g, mp_t *y, mp_t *r, mp_t *s, int return 0; if (!mpisless(ql, s, q) || mpiszero(ql, s)) return 0; - tmp = mpnew(pl); /* note pl! */ - memcpy(tmp, q, ql * MP_T_BYTES); /* tmp = q */ + tmp = mpnew(pl); /* note pl */ + mpcpy(ql, tmp, q); /* tmp = q */ mpdec(ql, tmp); /* tmp-- */ mpdec(ql, tmp); /* tmp-- */ w = mpnew(ql); mppow(ql, w, s, ql, tmp, q); /* w = s ^ tmp (s ^ -1) */ - u1 = mpnew(pl); /* u1 = 0 */ + u1 = mpnew(pl); /* note pl */ /* order is important here: h can be >= q */ - mpmult_add(ql, u1, w, hl, h, q); /* u1 += w * h */ - u2 = mpnew(pl); /* u2 = 0 */ - mpmult_add(ql, u2, w, ql, r, q); /* u2 += w * r */ + mpmult(ql, u1, w, hl, h, q); /* u1 = w * h */ + u2 = mpnew(ql); /* u2 = 0 */ + mpmult(ql, u2, w, ql, r, q); /* u2 = w * r */ free(w); gu1 = mpnew(pl); yu2 = mpnew(pl); - mppow(pl, gu1, g, pl, u1, p); /* gu1 = g ^ u1 */ - mppow(pl, yu2, y, pl, u2, p); /* yu2 = y ^ u2 */ - mpzero(pl, u1); /* u1 = 0 */ - mpmult_add(pl, u1, gu1, pl, yu2, p); /* u1 += gu1 * yu2 */ + mppow(pl, gu1, g, ql, u1, p); /* gu1 = g ^ u1 */ + mppow(pl, yu2, y, ql, u2, p); /* yu2 = y ^ u2 */ + mpmult(pl, u1, gu1, pl, yu2, p); /* u1 = gu1 * yu2 */ free(gu1); free(yu2); mpzero(ql, u2); u2[0] = 1; /* u2 = 1 */ - mpzero(ql, tmp); /* tmp = 0 */ - mpmult_add(ql, tmp, u2, pl, u1, q); /* tmp += u2 * u1 */ + mpmult(ql, tmp, u2, pl, u1, q); /* tmp = u2 * u1 */ free(u1); free(u2); #if 0 @@ -302,7 +317,7 @@ mpdsa(int pl, mp_t *p, int ql, mp_t *q, mp_t *g, mp_t *y, mp_t *r, mp_t *s, int return 1; } -static int +static int mprsa(int nl, mp_t *n, int el, mp_t *e, mp_t *m, mp_t *c) { mp_t *tmp; @@ -332,7 +347,7 @@ mprsa(int nl, mp_t *n, int el, mp_t *e, mp_t *m, mp_t *c) /* create mp with size tbits from data with size dbits */ static mp_t * -mpbuild(unsigned char *d, int dbits, int tbits, int *mplp) +mpbuild(const unsigned char *d, int dbits, int tbits, int *mplp) { int l = (tbits + MP_T_BITS - 1) / MP_T_BITS; int dl, i; @@ -352,36 +367,35 @@ mpbuild(unsigned char *d, int dbits, int tbits, int *mplp) return out; } -static unsigned char * -findmpi(unsigned char **mpip, int *mpilp, int maxbits, int *outlen) +static const unsigned char * +findmpi(const unsigned char **mpip, int *mpilp, int maxbits, int *outlen) { int mpil = *mpilp; - unsigned char *mpi = *mpip; - unsigned char *out = 0; + const unsigned char *mpi = *mpip; int bits, l; + *outlen = 0; if (mpil < 2) return 0; bits = mpi[0] << 8 | mpi[1]; l = 2 + (bits + 7) / 8; - if (bits > maxbits || mpil < l) - *mpilp = 0; - else + if (bits > maxbits || mpil < l || (bits && !mpi[2])) { - out = mpi + 2; - *outlen = bits; - *mpilp = mpil - l; - *mpip = mpi + l; + *mpilp = 0; + return 0; } - return out; + *outlen = bits; + *mpilp = mpil - l; + *mpip = mpi + l; + return mpi + 2; } int -solv_pgpvrfy(unsigned char *pub, int publ, unsigned char *sig, int sigl) +solv_pgpvrfy(const unsigned char *pub, int publ, const unsigned char *sig, int sigl) { int hashl; unsigned char *oid = 0; - unsigned char *mpi; + const unsigned char *mpi; int mpil; int res = 0; @@ -403,10 +417,18 @@ solv_pgpvrfy(unsigned char *pub, int publ, unsigned char *sig, int sigl) hashl = 32; /* SHA-256 */ oid = (unsigned char *)"\023\060\061\060\015\006\011\140\206\110\001\145\003\004\002\001\005\000\004\040"; break; + case 9: + hashl = 48; /* SHA-384 */ + oid = (unsigned char *)"\023\060\101\060\015\006\011\140\206\110\001\145\003\004\002\002\005\000\004\060"; + break; case 10: hashl = 64; /* SHA-512 */ oid = (unsigned char *)"\023\060\121\060\015\006\011\140\206\110\001\145\003\004\002\003\005\000\004\100"; break; + case 11: + hashl = 28; /* SHA-224 */ + oid = (unsigned char *)"\023\060\061\060\015\006\011\140\206\110\001\145\003\004\002\004\005\000\004\034"; + break; default: return 0; /* unsupported hash algo */ } @@ -416,7 +438,8 @@ solv_pgpvrfy(unsigned char *pub, int publ, unsigned char *sig, int sigl) { case 1: /* RSA */ { - unsigned char *n, *e, *m, *c; + const unsigned char *n, *e, *m; + unsigned char *c; int nlen, elen, mlen, clen; mp_t *nx, *ex, *mx, *cx; int nxl, exl; @@ -455,7 +478,7 @@ solv_pgpvrfy(unsigned char *pub, int publ, unsigned char *sig, int sigl) } case 17: /* DSA */ { - unsigned char *p, *q, *g, *y, *r, *s; + const unsigned char *p, *q, *g, *y, *r, *s; int plen, qlen, glen, ylen, rlen, slen, hlen; mp_t *px, *qx, *gx, *yx, *rx, *sx, *hx; int pxl, qxl, hxl;