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
00032 #include "postgres.h"
00033
00034 #include "px.h"
00035 #include "mbuf.h"
00036 #include "pgp.h"
00037
00038 static int
00039 calc_s2k_simple(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
00040 unsigned key_len)
00041 {
00042 unsigned md_rlen;
00043 uint8 buf[PGP_MAX_DIGEST];
00044 unsigned preload;
00045 unsigned remain;
00046 uint8 *dst = s2k->key;
00047
00048 md_rlen = px_md_result_size(md);
00049
00050 remain = s2k->key_len;
00051 preload = 0;
00052 while (remain > 0)
00053 {
00054 px_md_reset(md);
00055
00056 if (preload)
00057 {
00058 memset(buf, 0, preload);
00059 px_md_update(md, buf, preload);
00060 }
00061 preload++;
00062
00063 px_md_update(md, key, key_len);
00064 px_md_finish(md, buf);
00065
00066 if (remain > md_rlen)
00067 {
00068 memcpy(dst, buf, md_rlen);
00069 dst += md_rlen;
00070 remain -= md_rlen;
00071 }
00072 else
00073 {
00074 memcpy(dst, buf, remain);
00075 remain = 0;
00076 }
00077 }
00078 return 0;
00079 }
00080
00081 static int
00082 calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
00083 {
00084 unsigned md_rlen;
00085 uint8 buf[PGP_MAX_DIGEST];
00086 unsigned preload = 0;
00087 uint8 *dst;
00088 unsigned remain;
00089
00090 md_rlen = px_md_result_size(md);
00091
00092 dst = s2k->key;
00093 remain = s2k->key_len;
00094 while (remain > 0)
00095 {
00096 px_md_reset(md);
00097
00098 if (preload > 0)
00099 {
00100 memset(buf, 0, preload);
00101 px_md_update(md, buf, preload);
00102 }
00103 preload++;
00104
00105 px_md_update(md, s2k->salt, PGP_S2K_SALT);
00106 px_md_update(md, key, key_len);
00107 px_md_finish(md, buf);
00108
00109 if (remain > md_rlen)
00110 {
00111 memcpy(dst, buf, md_rlen);
00112 remain -= md_rlen;
00113 dst += md_rlen;
00114 }
00115 else
00116 {
00117 memcpy(dst, buf, remain);
00118 remain = 0;
00119 }
00120 }
00121 return 0;
00122 }
00123
00124 static int
00125 calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
00126 unsigned key_len)
00127 {
00128 unsigned md_rlen;
00129 uint8 buf[PGP_MAX_DIGEST];
00130 uint8 *dst;
00131 unsigned preload = 0;
00132 unsigned remain,
00133 c,
00134 cval,
00135 curcnt,
00136 count;
00137
00138 cval = s2k->iter;
00139 count = ((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6);
00140
00141 md_rlen = px_md_result_size(md);
00142
00143 remain = s2k->key_len;
00144 dst = s2k->key;
00145 while (remain > 0)
00146 {
00147 px_md_reset(md);
00148
00149 if (preload)
00150 {
00151 memset(buf, 0, preload);
00152 px_md_update(md, buf, preload);
00153 }
00154 preload++;
00155
00156 px_md_update(md, s2k->salt, PGP_S2K_SALT);
00157 px_md_update(md, key, key_len);
00158 curcnt = PGP_S2K_SALT + key_len;
00159
00160 while (curcnt < count)
00161 {
00162 if (curcnt + PGP_S2K_SALT < count)
00163 c = PGP_S2K_SALT;
00164 else
00165 c = count - curcnt;
00166 px_md_update(md, s2k->salt, c);
00167 curcnt += c;
00168
00169 if (curcnt + key_len < count)
00170 c = key_len;
00171 else if (curcnt < count)
00172 c = count - curcnt;
00173 else
00174 break;
00175 px_md_update(md, key, c);
00176 curcnt += c;
00177 }
00178 px_md_finish(md, buf);
00179
00180 if (remain > md_rlen)
00181 {
00182 memcpy(dst, buf, md_rlen);
00183 remain -= md_rlen;
00184 dst += md_rlen;
00185 }
00186 else
00187 {
00188 memcpy(dst, buf, remain);
00189 remain = 0;
00190 }
00191 }
00192 return 0;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 static int
00204 decide_count(unsigned rand_byte)
00205 {
00206 return 96 + (rand_byte & 0x1F);
00207 }
00208
00209 int
00210 pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
00211 {
00212 int res = 0;
00213 uint8 tmp;
00214
00215 s2k->mode = mode;
00216 s2k->digest_algo = digest_algo;
00217
00218 switch (s2k->mode)
00219 {
00220 case 0:
00221 break;
00222 case 1:
00223 res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
00224 break;
00225 case 3:
00226 res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
00227 if (res < 0)
00228 break;
00229 res = px_get_pseudo_random_bytes(&tmp, 1);
00230 if (res < 0)
00231 break;
00232 s2k->iter = decide_count(tmp);
00233 break;
00234 default:
00235 res = PXE_PGP_BAD_S2K_MODE;
00236 }
00237 return res;
00238 }
00239
00240 int
00241 pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
00242 {
00243 int res = 0;
00244
00245 GETBYTE(src, s2k->mode);
00246 GETBYTE(src, s2k->digest_algo);
00247 switch (s2k->mode)
00248 {
00249 case 0:
00250 break;
00251 case 1:
00252 res = pullf_read_fixed(src, 8, s2k->salt);
00253 break;
00254 case 3:
00255 res = pullf_read_fixed(src, 8, s2k->salt);
00256 if (res < 0)
00257 break;
00258 GETBYTE(src, s2k->iter);
00259 break;
00260 default:
00261 res = PXE_PGP_BAD_S2K_MODE;
00262 }
00263 return res;
00264 }
00265
00266 int
00267 pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
00268 {
00269 int res;
00270 PX_MD *md;
00271
00272 s2k->key_len = pgp_get_cipher_key_size(cipher);
00273 if (s2k->key_len <= 0)
00274 return PXE_PGP_UNSUPPORTED_CIPHER;
00275
00276 res = pgp_load_digest(s2k->digest_algo, &md);
00277 if (res < 0)
00278 return res;
00279
00280 switch (s2k->mode)
00281 {
00282 case 0:
00283 res = calc_s2k_simple(s2k, md, key, key_len);
00284 break;
00285 case 1:
00286 res = calc_s2k_salted(s2k, md, key, key_len);
00287 break;
00288 case 3:
00289 res = calc_s2k_iter_salted(s2k, md, key, key_len);
00290 break;
00291 default:
00292 res = PXE_PGP_BAD_S2K_MODE;
00293 }
00294 px_md_free(md);
00295 return res;
00296 }