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 <openssl/bn.h>
00034
00035 #include "px.h"
00036 #include "mbuf.h"
00037 #include "pgp.h"
00038
00039 static BIGNUM *
00040 mpi_to_bn(PGP_MPI *n)
00041 {
00042 BIGNUM *bn = BN_bin2bn(n->data, n->bytes, NULL);
00043
00044 if (!bn)
00045 return NULL;
00046 if (BN_num_bits(bn) != n->bits)
00047 {
00048 px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d",
00049 n->bits, BN_num_bits(bn));
00050 BN_clear_free(bn);
00051 return NULL;
00052 }
00053 return bn;
00054 }
00055
00056 static PGP_MPI *
00057 bn_to_mpi(BIGNUM *bn)
00058 {
00059 int res;
00060 PGP_MPI *n;
00061
00062 res = pgp_mpi_alloc(BN_num_bits(bn), &n);
00063 if (res < 0)
00064 return NULL;
00065
00066 if (BN_num_bytes(bn) != n->bytes)
00067 {
00068 px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d",
00069 BN_num_bytes(bn), n->bytes);
00070 pgp_mpi_free(n);
00071 return NULL;
00072 }
00073 BN_bn2bin(bn, n->data);
00074 return n;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 static int
00093 decide_k_bits(int p_bits)
00094 {
00095 if (p_bits <= 5120)
00096 return p_bits / 10 + 160;
00097 else
00098 return (p_bits / 8 + 200) * 3 / 2;
00099 }
00100
00101 int
00102 pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
00103 PGP_MPI **c1_p, PGP_MPI **c2_p)
00104 {
00105 int res = PXE_PGP_MATH_FAILED;
00106 int k_bits;
00107 BIGNUM *m = mpi_to_bn(_m);
00108 BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
00109 BIGNUM *g = mpi_to_bn(pk->pub.elg.g);
00110 BIGNUM *y = mpi_to_bn(pk->pub.elg.y);
00111 BIGNUM *k = BN_new();
00112 BIGNUM *yk = BN_new();
00113 BIGNUM *c1 = BN_new();
00114 BIGNUM *c2 = BN_new();
00115 BN_CTX *tmp = BN_CTX_new();
00116
00117 if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp)
00118 goto err;
00119
00120
00121
00122
00123 k_bits = decide_k_bits(BN_num_bits(p));
00124 if (!BN_rand(k, k_bits, 0, 0))
00125 goto err;
00126
00127
00128
00129
00130 if (!BN_mod_exp(c1, g, k, p, tmp))
00131 goto err;
00132 if (!BN_mod_exp(yk, y, k, p, tmp))
00133 goto err;
00134 if (!BN_mod_mul(c2, m, yk, p, tmp))
00135 goto err;
00136
00137
00138 *c1_p = bn_to_mpi(c1);
00139 *c2_p = bn_to_mpi(c2);
00140 if (*c1_p && *c2_p)
00141 res = 0;
00142 err:
00143 if (tmp)
00144 BN_CTX_free(tmp);
00145 if (c2)
00146 BN_clear_free(c2);
00147 if (c1)
00148 BN_clear_free(c1);
00149 if (yk)
00150 BN_clear_free(yk);
00151 if (k)
00152 BN_clear_free(k);
00153 if (y)
00154 BN_clear_free(y);
00155 if (g)
00156 BN_clear_free(g);
00157 if (p)
00158 BN_clear_free(p);
00159 if (m)
00160 BN_clear_free(m);
00161 return res;
00162 }
00163
00164 int
00165 pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
00166 PGP_MPI **msg_p)
00167 {
00168 int res = PXE_PGP_MATH_FAILED;
00169 BIGNUM *c1 = mpi_to_bn(_c1);
00170 BIGNUM *c2 = mpi_to_bn(_c2);
00171 BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
00172 BIGNUM *x = mpi_to_bn(pk->sec.elg.x);
00173 BIGNUM *c1x = BN_new();
00174 BIGNUM *div = BN_new();
00175 BIGNUM *m = BN_new();
00176 BN_CTX *tmp = BN_CTX_new();
00177
00178 if (!c1 || !c2 || !p || !x || !c1x || !div || !m || !tmp)
00179 goto err;
00180
00181
00182
00183
00184 if (!BN_mod_exp(c1x, c1, x, p, tmp))
00185 goto err;
00186 if (!BN_mod_inverse(div, c1x, p, tmp))
00187 goto err;
00188 if (!BN_mod_mul(m, c2, div, p, tmp))
00189 goto err;
00190
00191
00192 *msg_p = bn_to_mpi(m);
00193 if (*msg_p)
00194 res = 0;
00195 err:
00196 if (tmp)
00197 BN_CTX_free(tmp);
00198 if (m)
00199 BN_clear_free(m);
00200 if (div)
00201 BN_clear_free(div);
00202 if (c1x)
00203 BN_clear_free(c1x);
00204 if (x)
00205 BN_clear_free(x);
00206 if (p)
00207 BN_clear_free(p);
00208 if (c2)
00209 BN_clear_free(c2);
00210 if (c1)
00211 BN_clear_free(c1);
00212 return res;
00213 }
00214
00215 int
00216 pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
00217 {
00218 int res = PXE_PGP_MATH_FAILED;
00219 BIGNUM *m = mpi_to_bn(_m);
00220 BIGNUM *e = mpi_to_bn(pk->pub.rsa.e);
00221 BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
00222 BIGNUM *c = BN_new();
00223 BN_CTX *tmp = BN_CTX_new();
00224
00225 if (!m || !e || !n || !c || !tmp)
00226 goto err;
00227
00228
00229
00230
00231 if (!BN_mod_exp(c, m, e, n, tmp))
00232 goto err;
00233
00234 *c_p = bn_to_mpi(c);
00235 if (*c_p)
00236 res = 0;
00237 err:
00238 if (tmp)
00239 BN_CTX_free(tmp);
00240 if (c)
00241 BN_clear_free(c);
00242 if (n)
00243 BN_clear_free(n);
00244 if (e)
00245 BN_clear_free(e);
00246 if (m)
00247 BN_clear_free(m);
00248 return res;
00249 }
00250
00251 int
00252 pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
00253 {
00254 int res = PXE_PGP_MATH_FAILED;
00255 BIGNUM *c = mpi_to_bn(_c);
00256 BIGNUM *d = mpi_to_bn(pk->sec.rsa.d);
00257 BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
00258 BIGNUM *m = BN_new();
00259 BN_CTX *tmp = BN_CTX_new();
00260
00261 if (!m || !d || !n || !c || !tmp)
00262 goto err;
00263
00264
00265
00266
00267 if (!BN_mod_exp(m, c, d, n, tmp))
00268 goto err;
00269
00270 *m_p = bn_to_mpi(m);
00271 if (*m_p)
00272 res = 0;
00273 err:
00274 if (tmp)
00275 BN_CTX_free(tmp);
00276 if (m)
00277 BN_clear_free(m);
00278 if (n)
00279 BN_clear_free(n);
00280 if (d)
00281 BN_clear_free(d);
00282 if (c)
00283 BN_clear_free(c);
00284 return res;
00285 }