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 #include <gnutls_int.h>
00030 #include <gnutls_hash_int.h>
00031 #include <gnutls_errors.h>
00032
00033 static inline Gc_hash
00034 MHD__gnutls_mac2gc (enum MHD_GNUTLS_HashAlgorithm mac)
00035 {
00036 switch (mac)
00037 {
00038 case MHD_GNUTLS_MAC_NULL:
00039 return -1;
00040 break;
00041 case MHD_GNUTLS_MAC_SHA1:
00042 return GC_SHA1;
00043 break;
00044 case MHD_GNUTLS_MAC_SHA256:
00045 return GC_SHA256;
00046 break;
00047 case MHD_GNUTLS_MAC_MD5:
00048 return GC_MD5;
00049 break;
00050 default:
00051 MHD_gnutls_assert ();
00052 return -1;
00053 }
00054 return -1;
00055 }
00056
00057 GNUTLS_HASH_HANDLE
00058 MHD_gtls_hash_init (enum MHD_GNUTLS_HashAlgorithm algorithm)
00059 {
00060 mac_hd_t ret;
00061 int result;
00062
00063 ret = MHD_gnutls_malloc (sizeof (mac_hd_st));
00064 if (ret == NULL)
00065 {
00066 MHD_gnutls_assert ();
00067 return GNUTLS_HASH_FAILED;
00068 }
00069
00070 ret->algorithm = algorithm;
00071
00072 result = MHD_gc_hash_open (MHD__gnutls_mac2gc (algorithm), 0, &ret->handle);
00073 if (result)
00074 {
00075 MHD_gnutls_assert ();
00076 MHD_gnutls_free (ret);
00077 ret = GNUTLS_HASH_FAILED;
00078 }
00079
00080 return ret;
00081 }
00082
00083 int
00084 MHD_gnutls_hash_get_algo_len (enum MHD_GNUTLS_HashAlgorithm algorithm)
00085 {
00086 int ret;
00087
00088 ret = MHD_gc_hash_digest_length (MHD__gnutls_mac2gc (algorithm));
00089
00090 return ret;
00091
00092 }
00093
00094 int
00095 MHD_gnutls_hash (GNUTLS_HASH_HANDLE handle, const void *text, size_t textlen)
00096 {
00097 if (textlen > 0)
00098 MHD_gc_hash_write (handle->handle, textlen, text);
00099 return 0;
00100 }
00101
00102 GNUTLS_HASH_HANDLE
00103 MHD_gnutls_hash_copy (GNUTLS_HASH_HANDLE handle)
00104 {
00105 GNUTLS_HASH_HANDLE ret;
00106 int result;
00107
00108 ret = MHD_gnutls_malloc (sizeof (mac_hd_st));
00109
00110 if (ret == NULL)
00111 return GNUTLS_HASH_FAILED;
00112
00113 ret->algorithm = handle->algorithm;
00114 ret->key = NULL;
00115 ret->keysize = 0;
00116
00117 result = MHD_gc_hash_clone (handle->handle, &ret->handle);
00118
00119 if (result)
00120 {
00121 MHD_gnutls_free (ret);
00122 return GNUTLS_HASH_FAILED;
00123 }
00124
00125 return ret;
00126 }
00127
00128 void
00129 MHD_gnutls_hash_deinit (GNUTLS_HASH_HANDLE handle, void *digest)
00130 {
00131 const opaque *mac;
00132 int maclen;
00133
00134 maclen = MHD_gnutls_hash_get_algo_len (handle->algorithm);
00135
00136 mac = (unsigned char *) MHD_gc_hash_read (handle->handle);
00137 if (digest != NULL)
00138 memcpy (digest, mac, maclen);
00139
00140 MHD_gc_hash_close (handle->handle);
00141
00142 MHD_gnutls_free (handle);
00143 }
00144
00145
00146 mac_hd_t
00147 MHD_gtls_MHD_hmac_init (enum MHD_GNUTLS_HashAlgorithm algorithm,
00148 const void *key, int keylen)
00149 {
00150 mac_hd_t ret;
00151 int result;
00152
00153 ret = MHD_gnutls_malloc (sizeof (mac_hd_st));
00154 if (ret == NULL)
00155 return GNUTLS_MAC_FAILED;
00156
00157 result =
00158 MHD_gc_hash_open (MHD__gnutls_mac2gc (algorithm), GC_HMAC, &ret->handle);
00159 if (result)
00160 {
00161 MHD_gnutls_free (ret);
00162 return GNUTLS_MAC_FAILED;
00163 }
00164
00165 MHD_gc_hash_MHD_hmac_setkey (ret->handle, keylen, key);
00166
00167 ret->algorithm = algorithm;
00168 ret->key = key;
00169 ret->keysize = keylen;
00170
00171 return ret;
00172 }
00173
00174 void
00175 MHD_gnutls_MHD_hmac_deinit (mac_hd_t handle, void *digest)
00176 {
00177 const opaque *mac;
00178 int maclen;
00179
00180 maclen = MHD_gnutls_hash_get_algo_len (handle->algorithm);
00181
00182 mac = (unsigned char *) MHD_gc_hash_read (handle->handle);
00183
00184 if (digest != NULL)
00185 memcpy (digest, mac, maclen);
00186
00187 MHD_gc_hash_close (handle->handle);
00188
00189 MHD_gnutls_free (handle);
00190 }
00191
00192 inline static int
00193 get_padsize (enum MHD_GNUTLS_HashAlgorithm algorithm)
00194 {
00195 switch (algorithm)
00196 {
00197 case MHD_GNUTLS_MAC_MD5:
00198 return 48;
00199 case MHD_GNUTLS_MAC_SHA1:
00200 return 40;
00201 default:
00202 return 0;
00203 }
00204 }
00205
00206 mac_hd_t
00207 MHD_gnutls_mac_init_ssl3 (enum MHD_GNUTLS_HashAlgorithm algorithm, void *key,
00208 int keylen)
00209 {
00210 mac_hd_t ret;
00211 opaque ipad[48];
00212 int padsize;
00213
00214 padsize = get_padsize (algorithm);
00215 if (padsize == 0)
00216 {
00217 MHD_gnutls_assert ();
00218 return GNUTLS_MAC_FAILED;
00219 }
00220
00221 memset (ipad, 0x36, padsize);
00222
00223 ret = MHD_gtls_hash_init (algorithm);
00224 if (ret != GNUTLS_HASH_FAILED)
00225 {
00226 ret->key = key;
00227 ret->keysize = keylen;
00228
00229 if (keylen > 0)
00230 MHD_gnutls_hash (ret, key, keylen);
00231 MHD_gnutls_hash (ret, ipad, padsize);
00232 }
00233
00234 return ret;
00235 }
00236
00237 void
00238 MHD_gnutls_mac_deinit_ssl3 (mac_hd_t handle, void *digest)
00239 {
00240 opaque ret[MAX_HASH_SIZE];
00241 mac_hd_t td;
00242 opaque opad[48];
00243 int padsize;
00244 int block;
00245
00246 padsize = get_padsize (handle->algorithm);
00247 if (padsize == 0)
00248 {
00249 MHD_gnutls_assert ();
00250 return;
00251 }
00252
00253 memset (opad, 0x5C, padsize);
00254
00255 td = MHD_gtls_hash_init (handle->algorithm);
00256 if (td != GNUTLS_MAC_FAILED)
00257 {
00258 if (handle->keysize > 0)
00259 MHD_gnutls_hash (td, handle->key, handle->keysize);
00260
00261 MHD_gnutls_hash (td, opad, padsize);
00262 block = MHD_gnutls_hash_get_algo_len (handle->algorithm);
00263 MHD_gnutls_hash_deinit (handle, ret);
00264 MHD_gnutls_hash (td, ret, block);
00265
00266 MHD_gnutls_hash_deinit (td, digest);
00267 }
00268 }
00269
00270 void
00271 MHD_gnutls_mac_deinit_ssl3_handshake (mac_hd_t handle,
00272 void *digest, opaque * key,
00273 uint32_t key_size)
00274 {
00275 opaque ret[MAX_HASH_SIZE];
00276 mac_hd_t td;
00277 opaque opad[48];
00278 opaque ipad[48];
00279 int padsize;
00280 int block;
00281
00282 padsize = get_padsize (handle->algorithm);
00283 if (padsize == 0)
00284 {
00285 MHD_gnutls_assert ();
00286 return;
00287 }
00288
00289 memset (opad, 0x5C, padsize);
00290 memset (ipad, 0x36, padsize);
00291
00292 td = MHD_gtls_hash_init (handle->algorithm);
00293 if (td != GNUTLS_HASH_FAILED)
00294 {
00295 if (key_size > 0)
00296 MHD_gnutls_hash (td, key, key_size);
00297
00298 MHD_gnutls_hash (td, opad, padsize);
00299 block = MHD_gnutls_hash_get_algo_len (handle->algorithm);
00300
00301 if (key_size > 0)
00302 MHD_gnutls_hash (handle, key, key_size);
00303 MHD_gnutls_hash (handle, ipad, padsize);
00304 MHD_gnutls_hash_deinit (handle, ret);
00305
00306 MHD_gnutls_hash (td, ret, block);
00307
00308 MHD_gnutls_hash_deinit (td, digest);
00309 }
00310 }
00311
00312 static int
00313 ssl3_sha (int i, opaque * secret, int secret_len,
00314 opaque * rnd, int rnd_len, void *digest)
00315 {
00316 int j;
00317 opaque text1[26];
00318
00319 GNUTLS_HASH_HANDLE td;
00320
00321 for (j = 0; j < i + 1; j++)
00322 {
00323 text1[j] = 65 + i;
00324 }
00325
00326 td = MHD_gtls_hash_init (MHD_GNUTLS_MAC_SHA1);
00327 if (td == NULL)
00328 {
00329 MHD_gnutls_assert ();
00330 return GNUTLS_E_HASH_FAILED;
00331 }
00332
00333 MHD_gnutls_hash (td, text1, i + 1);
00334 MHD_gnutls_hash (td, secret, secret_len);
00335 MHD_gnutls_hash (td, rnd, rnd_len);
00336
00337 MHD_gnutls_hash_deinit (td, digest);
00338 return 0;
00339 }
00340
00341 static int
00342 ssl3_md5 (int i, opaque * secret, int secret_len,
00343 opaque * rnd, int rnd_len, void *digest)
00344 {
00345 opaque tmp[MAX_HASH_SIZE];
00346 mac_hd_t td;
00347 int ret;
00348
00349 td = MHD_gtls_hash_init (MHD_GNUTLS_MAC_MD5);
00350 if (td == NULL)
00351 {
00352 MHD_gnutls_assert ();
00353 return GNUTLS_E_HASH_FAILED;
00354 }
00355
00356 MHD_gnutls_hash (td, secret, secret_len);
00357
00358 ret = ssl3_sha (i, secret, secret_len, rnd, rnd_len, tmp);
00359 if (ret < 0)
00360 {
00361 MHD_gnutls_assert ();
00362 MHD_gnutls_hash_deinit (td, digest);
00363 return ret;
00364 }
00365
00366 MHD_gnutls_hash (td, tmp,
00367 MHD_gnutls_hash_get_algo_len (MHD_GNUTLS_MAC_SHA1));
00368
00369 MHD_gnutls_hash_deinit (td, digest);
00370 return 0;
00371 }
00372
00373 int
00374 MHD_gnutls_ssl3_hash_md5 (void *first, int first_len,
00375 void *second, int second_len, int ret_len,
00376 opaque * ret)
00377 {
00378 opaque digest[MAX_HASH_SIZE];
00379 mac_hd_t td;
00380 int block = MHD_gnutls_hash_get_algo_len (MHD_GNUTLS_MAC_MD5);
00381
00382 td = MHD_gtls_hash_init (MHD_GNUTLS_MAC_MD5);
00383 if (td == NULL)
00384 {
00385 MHD_gnutls_assert ();
00386 return GNUTLS_E_HASH_FAILED;
00387 }
00388
00389 MHD_gnutls_hash (td, first, first_len);
00390 MHD_gnutls_hash (td, second, second_len);
00391
00392 MHD_gnutls_hash_deinit (td, digest);
00393
00394 if (ret_len > block)
00395 {
00396 MHD_gnutls_assert ();
00397 return GNUTLS_E_INTERNAL_ERROR;
00398 }
00399
00400 memcpy (ret, digest, ret_len);
00401
00402 return 0;
00403
00404 }
00405
00406 int
00407 MHD_gnutls_ssl3_generate_random (void *secret, int secret_len,
00408 void *rnd, int rnd_len,
00409 int ret_bytes, opaque * ret)
00410 {
00411 int i = 0, copy, output_bytes;
00412 opaque digest[MAX_HASH_SIZE];
00413 int block = MHD_gnutls_hash_get_algo_len (MHD_GNUTLS_MAC_MD5);
00414 int result, times;
00415
00416 output_bytes = 0;
00417 do
00418 {
00419 output_bytes += block;
00420 }
00421 while (output_bytes < ret_bytes);
00422
00423 times = output_bytes / block;
00424
00425 for (i = 0; i < times; i++)
00426 {
00427
00428 result = ssl3_md5 (i, secret, secret_len, rnd, rnd_len, digest);
00429 if (result < 0)
00430 {
00431 MHD_gnutls_assert ();
00432 return result;
00433 }
00434
00435 if ((1 + i) * block < ret_bytes)
00436 {
00437 copy = block;
00438 }
00439 else
00440 {
00441 copy = ret_bytes - (i) * block;
00442 }
00443
00444 memcpy (&ret[i * block], digest, copy);
00445 }
00446
00447 return 0;
00448 }