00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "postgres.h"
00032
00033 #include "imath.h"
00034
00035 #include "px.h"
00036 #include "mbuf.h"
00037 #include "pgp.h"
00038
00039 static mpz_t *
00040 mp_new()
00041 {
00042 mpz_t *mp = mp_int_alloc();
00043
00044 mp_int_init_size(mp, 256);
00045 return mp;
00046 }
00047
00048 static void
00049 mp_clear_free(mpz_t *a)
00050 {
00051 if (!a)
00052 return;
00053
00054 mp_int_free(a);
00055 }
00056
00057
00058 static int
00059 mp_px_rand(uint32 bits, mpz_t *res)
00060 {
00061 int err;
00062 unsigned bytes = (bits + 7) / 8;
00063 int last_bits = bits & 7;
00064 uint8 *buf;
00065
00066 buf = px_alloc(bytes);
00067 err = px_get_random_bytes(buf, bytes);
00068 if (err < 0)
00069 {
00070 px_free(buf);
00071 return err;
00072 }
00073
00074
00075 if (last_bits)
00076 {
00077 buf[0] >>= 8 - last_bits;
00078 buf[0] |= 1 << (last_bits - 1);
00079 }
00080 else
00081 buf[0] |= 1 << 7;
00082
00083 mp_int_read_unsigned(res, buf, bytes);
00084
00085 px_free(buf);
00086
00087 return 0;
00088 }
00089
00090 static void
00091 mp_modmul(mpz_t *a, mpz_t *b, mpz_t *p, mpz_t *res)
00092 {
00093 mpz_t *tmp = mp_new();
00094
00095 mp_int_mul(a, b, tmp);
00096 mp_int_mod(tmp, p, res);
00097 mp_clear_free(tmp);
00098 }
00099
00100 static mpz_t *
00101 mpi_to_bn(PGP_MPI *n)
00102 {
00103 mpz_t *bn = mp_new();
00104
00105 mp_int_read_unsigned(bn, n->data, n->bytes);
00106
00107 if (!bn)
00108 return NULL;
00109 if (mp_int_count_bits(bn) != n->bits)
00110 {
00111 px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d",
00112 n->bits, mp_int_count_bits(bn));
00113 mp_clear_free(bn);
00114 return NULL;
00115 }
00116 return bn;
00117 }
00118
00119 static PGP_MPI *
00120 bn_to_mpi(mpz_t *bn)
00121 {
00122 int res;
00123 PGP_MPI *n;
00124 int bytes;
00125
00126 res = pgp_mpi_alloc(mp_int_count_bits(bn), &n);
00127 if (res < 0)
00128 return NULL;
00129
00130 bytes = (mp_int_count_bits(bn) + 7) / 8;
00131 if (bytes != n->bytes)
00132 {
00133 px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d",
00134 bytes, n->bytes);
00135 pgp_mpi_free(n);
00136 return NULL;
00137 }
00138 mp_int_to_unsigned(bn, n->data, n->bytes);
00139 return n;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 static int
00158 decide_k_bits(int p_bits)
00159 {
00160 if (p_bits <= 5120)
00161 return p_bits / 10 + 160;
00162 else
00163 return (p_bits / 8 + 200) * 3 / 2;
00164 }
00165
00166 int
00167 pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
00168 PGP_MPI **c1_p, PGP_MPI **c2_p)
00169 {
00170 int res = PXE_PGP_MATH_FAILED;
00171 int k_bits;
00172 mpz_t *m = mpi_to_bn(_m);
00173 mpz_t *p = mpi_to_bn(pk->pub.elg.p);
00174 mpz_t *g = mpi_to_bn(pk->pub.elg.g);
00175 mpz_t *y = mpi_to_bn(pk->pub.elg.y);
00176 mpz_t *k = mp_new();
00177 mpz_t *yk = mp_new();
00178 mpz_t *c1 = mp_new();
00179 mpz_t *c2 = mp_new();
00180
00181 if (!m || !p || !g || !y || !k || !yk || !c1 || !c2)
00182 goto err;
00183
00184
00185
00186
00187 k_bits = decide_k_bits(mp_int_count_bits(p));
00188 res = mp_px_rand(k_bits, k);
00189 if (res < 0)
00190 return res;
00191
00192
00193
00194
00195 mp_int_exptmod(g, k, p, c1);
00196 mp_int_exptmod(y, k, p, yk);
00197 mp_modmul(m, yk, p, c2);
00198
00199
00200 *c1_p = bn_to_mpi(c1);
00201 *c2_p = bn_to_mpi(c2);
00202 if (*c1_p && *c2_p)
00203 res = 0;
00204 err:
00205 mp_clear_free(c2);
00206 mp_clear_free(c1);
00207 mp_clear_free(yk);
00208 mp_clear_free(k);
00209 mp_clear_free(y);
00210 mp_clear_free(g);
00211 mp_clear_free(p);
00212 mp_clear_free(m);
00213 return res;
00214 }
00215
00216 int
00217 pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
00218 PGP_MPI **msg_p)
00219 {
00220 int res = PXE_PGP_MATH_FAILED;
00221 mpz_t *c1 = mpi_to_bn(_c1);
00222 mpz_t *c2 = mpi_to_bn(_c2);
00223 mpz_t *p = mpi_to_bn(pk->pub.elg.p);
00224 mpz_t *x = mpi_to_bn(pk->sec.elg.x);
00225 mpz_t *c1x = mp_new();
00226 mpz_t *div = mp_new();
00227 mpz_t *m = mp_new();
00228
00229 if (!c1 || !c2 || !p || !x || !c1x || !div || !m)
00230 goto err;
00231
00232
00233
00234
00235 mp_int_exptmod(c1, x, p, c1x);
00236 mp_int_invmod(c1x, p, div);
00237 mp_modmul(c2, div, p, m);
00238
00239
00240 *msg_p = bn_to_mpi(m);
00241 if (*msg_p)
00242 res = 0;
00243 err:
00244 mp_clear_free(m);
00245 mp_clear_free(div);
00246 mp_clear_free(c1x);
00247 mp_clear_free(x);
00248 mp_clear_free(p);
00249 mp_clear_free(c2);
00250 mp_clear_free(c1);
00251 return res;
00252 }
00253
00254 int
00255 pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
00256 {
00257 int res = PXE_PGP_MATH_FAILED;
00258 mpz_t *m = mpi_to_bn(_m);
00259 mpz_t *e = mpi_to_bn(pk->pub.rsa.e);
00260 mpz_t *n = mpi_to_bn(pk->pub.rsa.n);
00261 mpz_t *c = mp_new();
00262
00263 if (!m || !e || !n || !c)
00264 goto err;
00265
00266
00267
00268
00269 mp_int_exptmod(m, e, n, c);
00270
00271 *c_p = bn_to_mpi(c);
00272 if (*c_p)
00273 res = 0;
00274 err:
00275 mp_clear_free(c);
00276 mp_clear_free(n);
00277 mp_clear_free(e);
00278 mp_clear_free(m);
00279 return res;
00280 }
00281
00282 int
00283 pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
00284 {
00285 int res = PXE_PGP_MATH_FAILED;
00286 mpz_t *c = mpi_to_bn(_c);
00287 mpz_t *d = mpi_to_bn(pk->sec.rsa.d);
00288 mpz_t *n = mpi_to_bn(pk->pub.rsa.n);
00289 mpz_t *m = mp_new();
00290
00291 if (!m || !d || !n || !c)
00292 goto err;
00293
00294
00295
00296
00297 mp_int_exptmod(c, d, n, m);
00298
00299 *m_p = bn_to_mpi(m);
00300 if (*m_p)
00301 res = 0;
00302 err:
00303 mp_clear_free(m);
00304 mp_clear_free(n);
00305 mp_clear_free(d);
00306 mp_clear_free(c);
00307 return res;
00308 }