CyaSSL is an SSL library for devices like mbed.

Dependents:   cyassl-client Sync

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers keys.c Source File

keys.c

00001 /* keys.c
00002  *
00003  * Copyright (C) 2006-2009 Sawtooth Consulting Ltd.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 
00023 
00024 #include "cyassl_int.h"
00025 #include "cyassl_error.h"
00026 #ifdef SHOW_SECRETS
00027     #include <stdio.h>
00028 #endif
00029 
00030 
00031 #ifndef NO_TLS
00032     int MakeTlsMasterSecret(SSL*);
00033     void TLS_hmac(SSL* ssl, byte* digest, const byte* buffer, word32 sz,
00034                   int content, int verify);
00035 #endif
00036 
00037 
00038 
00039 int SetCipherSpecs(SSL* ssl)
00040 {
00041     switch (ssl->options.cipherSuite) {
00042 
00043 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
00044     case SSL_RSA_WITH_RC4_128_SHA :
00045         ssl->specs.bulk_cipher_algorithm = rc4;
00046         ssl->specs.cipher_type           = stream;
00047         ssl->specs.mac_algorithm         = sha_mac;
00048         ssl->specs.kea                   = rsa_kea;
00049         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00050         ssl->specs.pad_size              = PAD_SHA;
00051         ssl->specs.key_size              = RC4_KEY_SIZE;
00052         ssl->specs.iv_size               = 0;
00053         ssl->specs.block_size            = 0;
00054 
00055         break;
00056 #endif
00057 
00058 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
00059     case TLS_NTRU_RSA_WITH_RC4_128_SHA :
00060         ssl->specs.bulk_cipher_algorithm = rc4;
00061         ssl->specs.cipher_type           = stream;
00062         ssl->specs.mac_algorithm         = sha_mac;
00063         ssl->specs.kea                   = ntru_kea;
00064         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00065         ssl->specs.pad_size              = PAD_SHA;
00066         ssl->specs.key_size              = RC4_KEY_SIZE;
00067         ssl->specs.iv_size               = 0;
00068         ssl->specs.block_size            = 0;
00069 
00070         break;
00071 #endif
00072 
00073 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
00074     case SSL_RSA_WITH_RC4_128_MD5 :
00075         ssl->specs.bulk_cipher_algorithm = rc4;
00076         ssl->specs.cipher_type           = stream;
00077         ssl->specs.mac_algorithm         = md5_mac;
00078         ssl->specs.kea                   = rsa_kea;
00079         ssl->specs.hash_size             = MD5_DIGEST_SIZE;
00080         ssl->specs.pad_size              = PAD_MD5;
00081         ssl->specs.key_size              = RC4_KEY_SIZE;
00082         ssl->specs.iv_size               = 0;
00083         ssl->specs.block_size            = 0;
00084 
00085         break;
00086 #endif
00087 
00088 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
00089     case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
00090         ssl->specs.bulk_cipher_algorithm = triple_des;
00091         ssl->specs.cipher_type           = block;
00092         ssl->specs.mac_algorithm         = sha_mac;
00093         ssl->specs.kea                   = rsa_kea;
00094         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00095         ssl->specs.pad_size              = PAD_SHA;
00096         ssl->specs.key_size              = DES3_KEY_SIZE;
00097         ssl->specs.block_size            = DES_BLOCK_SIZE;
00098         ssl->specs.iv_size               = DES_IV_SIZE;
00099 
00100         break;
00101 #endif
00102 
00103 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
00104     case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
00105         ssl->specs.bulk_cipher_algorithm = triple_des;
00106         ssl->specs.cipher_type           = block;
00107         ssl->specs.mac_algorithm         = sha_mac;
00108         ssl->specs.kea                   = ntru_kea;
00109         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00110         ssl->specs.pad_size              = PAD_SHA;
00111         ssl->specs.key_size              = DES3_KEY_SIZE;
00112         ssl->specs.block_size            = DES_BLOCK_SIZE;
00113         ssl->specs.iv_size               = DES_IV_SIZE;
00114 
00115         break;
00116 #endif
00117 
00118 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
00119     case TLS_RSA_WITH_AES_128_CBC_SHA :
00120         ssl->specs.bulk_cipher_algorithm = aes;
00121         ssl->specs.cipher_type           = block;
00122         ssl->specs.mac_algorithm         = sha_mac;
00123         ssl->specs.kea                   = rsa_kea;
00124         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00125         ssl->specs.pad_size              = PAD_SHA;
00126         ssl->specs.key_size              = AES_128_KEY_SIZE;
00127         ssl->specs.block_size            = AES_BLOCK_SIZE;
00128         ssl->specs.iv_size               = AES_IV_SIZE;
00129 
00130         break;
00131 #endif
00132 
00133 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
00134     case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
00135         ssl->specs.bulk_cipher_algorithm = aes;
00136         ssl->specs.cipher_type           = block;
00137         ssl->specs.mac_algorithm         = sha_mac;
00138         ssl->specs.kea                   = ntru_kea;
00139         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00140         ssl->specs.pad_size              = PAD_SHA;
00141         ssl->specs.key_size              = AES_128_KEY_SIZE;
00142         ssl->specs.block_size            = AES_BLOCK_SIZE;
00143         ssl->specs.iv_size               = AES_IV_SIZE;
00144 
00145         break;
00146 #endif
00147 
00148 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
00149     case TLS_RSA_WITH_AES_256_CBC_SHA :
00150         ssl->specs.bulk_cipher_algorithm = aes;
00151         ssl->specs.cipher_type           = block;
00152         ssl->specs.mac_algorithm         = sha_mac;
00153         ssl->specs.kea                   = rsa_kea;
00154         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00155         ssl->specs.pad_size              = PAD_SHA;
00156         ssl->specs.key_size              = AES_256_KEY_SIZE;
00157         ssl->specs.block_size            = AES_BLOCK_SIZE;
00158         ssl->specs.iv_size               = AES_IV_SIZE;
00159 
00160         break;
00161 #endif
00162 
00163 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
00164     case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
00165         ssl->specs.bulk_cipher_algorithm = aes;
00166         ssl->specs.cipher_type           = block;
00167         ssl->specs.mac_algorithm         = sha_mac;
00168         ssl->specs.kea                   = ntru_kea;
00169         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00170         ssl->specs.pad_size              = PAD_SHA;
00171         ssl->specs.key_size              = AES_256_KEY_SIZE;
00172         ssl->specs.block_size            = AES_BLOCK_SIZE;
00173         ssl->specs.iv_size               = AES_IV_SIZE;
00174 
00175         break;
00176 #endif
00177 
00178 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
00179     case TLS_PSK_WITH_AES_128_CBC_SHA :
00180         ssl->specs.bulk_cipher_algorithm = aes;
00181         ssl->specs.cipher_type           = block;
00182         ssl->specs.mac_algorithm         = sha_mac;
00183         ssl->specs.kea                   = psk_kea;
00184         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00185         ssl->specs.pad_size              = PAD_SHA;
00186         ssl->specs.key_size              = AES_128_KEY_SIZE;
00187         ssl->specs.block_size            = AES_BLOCK_SIZE;
00188         ssl->specs.iv_size               = AES_IV_SIZE;
00189 
00190         ssl->options.usingPSK_cipher     = 1;
00191         break;
00192 #endif
00193 
00194 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
00195     case TLS_PSK_WITH_AES_256_CBC_SHA :
00196         ssl->specs.bulk_cipher_algorithm = aes;
00197         ssl->specs.cipher_type           = block;
00198         ssl->specs.mac_algorithm         = sha_mac;
00199         ssl->specs.kea                   = psk_kea;
00200         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00201         ssl->specs.pad_size              = PAD_SHA;
00202         ssl->specs.key_size              = AES_256_KEY_SIZE;
00203         ssl->specs.block_size            = AES_BLOCK_SIZE;
00204         ssl->specs.iv_size               = AES_IV_SIZE;
00205 
00206         ssl->options.usingPSK_cipher     = 1;
00207         break;
00208 #endif
00209 
00210 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
00211     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
00212         ssl->specs.bulk_cipher_algorithm = aes;
00213         ssl->specs.cipher_type           = block;
00214         ssl->specs.mac_algorithm         = sha_mac;
00215         ssl->specs.kea                   = diffie_hellman_kea;
00216         ssl->specs.sig_algo              = rsa_sa_algo;
00217         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00218         ssl->specs.pad_size              = PAD_SHA;
00219         ssl->specs.key_size              = AES_128_KEY_SIZE;
00220         ssl->specs.block_size            = AES_BLOCK_SIZE;
00221         ssl->specs.iv_size               = AES_IV_SIZE;
00222 
00223         break;
00224 #endif
00225 
00226 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
00227     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
00228         ssl->specs.bulk_cipher_algorithm = aes;
00229         ssl->specs.cipher_type           = block;
00230         ssl->specs.mac_algorithm         = sha_mac;
00231         ssl->specs.kea                   = diffie_hellman_kea;
00232         ssl->specs.sig_algo              = rsa_sa_algo;
00233         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00234         ssl->specs.pad_size              = PAD_SHA;
00235         ssl->specs.key_size              = AES_256_KEY_SIZE;
00236         ssl->specs.block_size            = AES_BLOCK_SIZE;
00237         ssl->specs.iv_size               = AES_IV_SIZE;
00238 
00239         break;
00240 #endif
00241 
00242 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_MD5
00243     case TLS_RSA_WITH_HC_128_CBC_MD5 :
00244         ssl->specs.bulk_cipher_algorithm = hc128;
00245         ssl->specs.cipher_type           = stream;
00246         ssl->specs.mac_algorithm         = md5_mac;
00247         ssl->specs.kea                   = rsa_kea;
00248         ssl->specs.hash_size             = MD5_DIGEST_SIZE;
00249         ssl->specs.pad_size              = PAD_MD5;
00250         ssl->specs.key_size              = HC_128_KEY_SIZE;
00251         ssl->specs.block_size            = 0;
00252         ssl->specs.iv_size               = HC_128_IV_SIZE;
00253 
00254         break;
00255 #endif
00256             
00257 #ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_SHA
00258         case TLS_RSA_WITH_HC_128_CBC_SHA :
00259             ssl->specs.bulk_cipher_algorithm = hc128;
00260             ssl->specs.cipher_type           = stream;
00261             ssl->specs.mac_algorithm         = sha_mac;
00262             ssl->specs.kea                   = rsa_kea;
00263             ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00264             ssl->specs.pad_size              = PAD_SHA;
00265             ssl->specs.key_size              = HC_128_KEY_SIZE;
00266             ssl->specs.block_size            = 0;
00267             ssl->specs.iv_size               = HC_128_IV_SIZE;
00268             
00269             break;
00270 #endif
00271 
00272 #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA
00273     case TLS_RSA_WITH_RABBIT_CBC_SHA :
00274         ssl->specs.bulk_cipher_algorithm = rabbit;
00275         ssl->specs.cipher_type           = stream;
00276         ssl->specs.mac_algorithm         = sha_mac;
00277         ssl->specs.kea                   = rsa_kea;
00278         ssl->specs.hash_size             = SHA_DIGEST_SIZE;
00279         ssl->specs.pad_size              = PAD_SHA;
00280         ssl->specs.key_size              = RABBIT_KEY_SIZE;
00281         ssl->specs.block_size            = 0;
00282         ssl->specs.iv_size               = RABBIT_IV_SIZE;
00283 
00284         break;
00285 #endif
00286 
00287     default:
00288         return UNSUPPORTED_SUITE;
00289     }
00290 
00291     /* set TLS if it hasn't been turned off */
00292     if (ssl->version.major == 3 && ssl->version.minor >= 1) {
00293 #ifndef NO_TLS
00294         ssl->options.tls = 1;
00295         ssl->hmac = TLS_hmac;
00296         if (ssl->version.minor == 2)
00297             ssl->options.tls1_1 = 1;
00298 #endif
00299     }
00300 
00301 #ifdef CYASSL_DTLS
00302     if (ssl->options.dtls)
00303         ssl->hmac = TLS_hmac;
00304 #endif
00305 
00306     return 0;
00307 }
00308 
00309 
00310 enum KeyStuff {
00311     MASTER_ROUNDS = 3,
00312     PREFIX        = 3,     /* up to three letters for master prefix */
00313     KEY_PREFIX    = 7      /* up to 7 prefix letters for key rounds */
00314 
00315 
00316 };
00317 
00318 
00319 /* true or false, zero for error */
00320 static int SetPrefix(byte* sha_input, int index)
00321 {
00322     switch (index) {
00323     case 0:
00324         XMEMCPY(sha_input, "A", 1);
00325         break;
00326     case 1:
00327         XMEMCPY(sha_input, "BB", 2);
00328         break;
00329     case 2:
00330         XMEMCPY(sha_input, "CCC", 3);
00331         break;
00332     case 3:
00333         XMEMCPY(sha_input, "DDDD", 4);
00334         break;
00335     case 4:
00336         XMEMCPY(sha_input, "EEEEE", 5);
00337         break;
00338     case 5:
00339         XMEMCPY(sha_input, "FFFFFF", 6);
00340         break;
00341     case 6:
00342         XMEMCPY(sha_input, "GGGGGGG", 7);
00343         break;
00344     default:
00345         return 0; 
00346     }
00347     return 1;
00348 }
00349 
00350 
00351 static int SetKeys(Ciphers* encrypt, Ciphers* decrypt, Keys* keys,
00352                    CipherSpecs* specs, byte side)
00353 {
00354 #ifdef BUILD_ARC4
00355     word32 sz = specs->key_size;
00356     if (specs->bulk_cipher_algorithm == rc4) {
00357         if (side == CLIENT_END) {
00358             Arc4SetKey(&encrypt->arc4, keys->client_write_key, sz);
00359             Arc4SetKey(&decrypt->arc4, keys->server_write_key, sz);
00360         }
00361         else {
00362             Arc4SetKey(&encrypt->arc4, keys->server_write_key, sz);
00363             Arc4SetKey(&decrypt->arc4, keys->client_write_key, sz);
00364         }
00365     }
00366 #endif
00367     
00368 #ifdef BUILD_HC128
00369     if (specs->bulk_cipher_algorithm == hc128) {
00370         if (side == CLIENT_END) {
00371             Hc128_SetKey(&encrypt->hc128, keys->client_write_key,
00372                                           keys->client_write_IV);
00373             Hc128_SetKey(&decrypt->hc128, keys->server_write_key,
00374                                           keys->server_write_IV);
00375         }
00376         else {
00377             Hc128_SetKey(&encrypt->hc128, keys->server_write_key,
00378                                          keys->server_write_IV);
00379             Hc128_SetKey(&decrypt->hc128, keys->client_write_key,
00380                                          keys->client_write_IV);
00381         }
00382     }
00383 #endif
00384     
00385 #ifdef BUILD_RABBIT
00386     if (specs->bulk_cipher_algorithm == rabbit) {
00387         if (side == CLIENT_END) {
00388             RabbitSetKey(&encrypt->rabbit, keys->client_write_key,
00389                                            keys->client_write_IV);
00390             RabbitSetKey(&decrypt->rabbit, keys->server_write_key,
00391                                            keys->server_write_IV);
00392         }
00393         else {
00394             RabbitSetKey(&encrypt->rabbit, keys->server_write_key,
00395                                            keys->server_write_IV);
00396             RabbitSetKey(&decrypt->rabbit, keys->client_write_key,
00397                                            keys->client_write_IV);
00398         }
00399     }
00400 #endif
00401     
00402 #ifdef BUILD_DES3
00403     if (specs->bulk_cipher_algorithm == triple_des) {
00404         if (side == CLIENT_END) {
00405             Des3_SetKey(&encrypt->des3, keys->client_write_key,
00406                         keys->client_write_IV, DES_ENCRYPTION);
00407             Des3_SetKey(&decrypt->des3, keys->server_write_key,
00408                         keys->server_write_IV, DES_DECRYPTION);
00409         }
00410         else {
00411             Des3_SetKey(&encrypt->des3, keys->server_write_key,
00412                         keys->server_write_IV, DES_ENCRYPTION);
00413             Des3_SetKey(&decrypt->des3, keys->client_write_key,
00414                 keys->client_write_IV, DES_DECRYPTION);
00415         }
00416     }
00417 #endif
00418 
00419 #ifdef BUILD_AES
00420     if (specs->bulk_cipher_algorithm == aes) {
00421         if (side == CLIENT_END) {
00422             AesSetKey(&encrypt->aes, keys->client_write_key,
00423                       specs->key_size, keys->client_write_IV,
00424                       AES_ENCRYPTION);
00425             AesSetKey(&decrypt->aes, keys->server_write_key,
00426                       specs->key_size, keys->server_write_IV,
00427                       AES_DECRYPTION);
00428         }
00429         else {
00430             AesSetKey(&encrypt->aes, keys->server_write_key,
00431                       specs->key_size, keys->server_write_IV,
00432                       AES_ENCRYPTION);
00433             AesSetKey(&decrypt->aes, keys->client_write_key,
00434                       specs->key_size, keys->client_write_IV,
00435                       AES_DECRYPTION);
00436         }
00437     }
00438 #endif
00439 
00440     keys->sequence_number      = 0;
00441     keys->peer_sequence_number = 0;
00442     keys->encryptionOn         = 0;
00443 
00444     return 0;
00445 }
00446 
00447 
00448 /* TLS can call too */
00449 int StoreKeys(SSL* ssl, const byte* keyData)
00450 {
00451     int sz = ssl->specs.hash_size, i;
00452 
00453     XMEMCPY(ssl->keys.client_write_MAC_secret, keyData, sz);
00454     i = sz;
00455     XMEMCPY(ssl->keys.server_write_MAC_secret,&keyData[i], sz);
00456     i += sz;
00457 
00458     sz = ssl->specs.key_size;
00459     XMEMCPY(ssl->keys.client_write_key, &keyData[i], sz);
00460     i += sz;
00461     XMEMCPY(ssl->keys.server_write_key, &keyData[i], sz);
00462     i += sz;
00463 
00464     sz = ssl->specs.iv_size;
00465     XMEMCPY(ssl->keys.client_write_IV, &keyData[i], sz);
00466     i += sz;
00467     XMEMCPY(ssl->keys.server_write_IV, &keyData[i], sz);
00468 
00469     return SetKeys(&ssl->encrypt, &ssl->decrypt, &ssl->keys, &ssl->specs,
00470                    ssl->options.side);
00471 }
00472 
00473 
00474 int DeriveKeys(SSL* ssl)
00475 {
00476     int length = 2 * ssl->specs.hash_size + 
00477                  2 * ssl->specs.key_size  +
00478                  2 * ssl->specs.iv_size;
00479     int rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i;
00480 
00481     byte shaOutput[SHA_DIGEST_SIZE];
00482     byte md5Input[SECRET_LEN + SHA_DIGEST_SIZE];
00483     byte shaInput[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN];
00484   
00485     Md5 md5;
00486     Sha sha;
00487 
00488     byte keyData[KEY_PREFIX * MD5_DIGEST_SIZE];  /* max size */
00489 
00490     InitMd5(&md5);
00491     InitSha(&sha);
00492 
00493     XMEMCPY(md5Input, ssl->arrays.masterSecret, SECRET_LEN);
00494 
00495     for (i = 0; i < rounds; ++i) {
00496         int j   = i + 1;
00497         int idx = j;
00498 
00499         if (!SetPrefix(shaInput, i)) {
00500             return PREFIX_ERROR;
00501         }
00502 
00503         XMEMCPY(shaInput + idx, ssl->arrays.masterSecret, SECRET_LEN);
00504         idx += SECRET_LEN;
00505         XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN);
00506         idx += RAN_LEN;
00507         XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN);
00508         idx += RAN_LEN;
00509 
00510         ShaUpdate(&sha, shaInput, sizeof(shaInput) - KEY_PREFIX + j);
00511         ShaFinal(&sha, shaOutput);
00512 
00513         XMEMCPY(&md5Input[SECRET_LEN], shaOutput, SHA_DIGEST_SIZE);
00514         Md5Update(&md5, md5Input, sizeof(md5Input));
00515         Md5Final(&md5, keyData + i * MD5_DIGEST_SIZE);
00516     }
00517 
00518     return StoreKeys(ssl, keyData);
00519 }
00520 
00521 
00522 void CleanPreMaster(SSL* ssl)
00523 {
00524     int i, sz = ssl->arrays.preMasterSz;
00525 
00526     for (i = 0; i < sz; i++)
00527         ssl->arrays.preMasterSecret[i] = 0;
00528 
00529     RNG_GenerateBlock(&ssl->rng, ssl->arrays.preMasterSecret, sz);
00530 
00531     for (i = 0; i < sz; i++)
00532         ssl->arrays.preMasterSecret[i] = 0;
00533 
00534 }
00535 
00536 
00537 /* Create and store the master secret see page 32, 6.1 */
00538 int MakeMasterSecret(SSL* ssl)
00539 {
00540     byte   shaOutput[SHA_DIGEST_SIZE];
00541     byte   md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE];
00542     byte   shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
00543     int    i;
00544     word32 idx;
00545     word32 pmsSz = ssl->arrays.preMasterSz;
00546 
00547     Md5 md5;
00548     Sha sha;
00549 
00550 #ifdef SHOW_SECRETS
00551     {
00552         int j;
00553         printf("pre master secret: ");
00554         for (j = 0; j < pmsSz; j++)
00555             printf("%02x", ssl->arrays.preMasterSecret[j]);
00556         printf("\n");
00557     }
00558 #endif
00559 
00560 #ifndef NO_TLS
00561     if (ssl->options.tls) return MakeTlsMasterSecret(ssl);
00562 #endif
00563 
00564     InitMd5(&md5);
00565     InitSha(&sha);
00566 
00567     XMEMCPY(md5Input, ssl->arrays.preMasterSecret, pmsSz);
00568 
00569     for (i = 0; i < MASTER_ROUNDS; ++i) {
00570         byte prefix[PREFIX];
00571         if (!SetPrefix(prefix, i)) {
00572             return PREFIX_ERROR;
00573         }
00574 
00575         idx = 0;
00576         XMEMCPY(shaInput, prefix, i + 1);
00577         idx += i + 1;
00578 
00579         XMEMCPY(shaInput + idx, ssl->arrays.preMasterSecret, pmsSz);
00580         idx += pmsSz;
00581         XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN);
00582         idx += RAN_LEN;
00583         XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN);
00584         idx += RAN_LEN;
00585         ShaUpdate(&sha, shaInput, idx);
00586         ShaFinal(&sha, shaOutput);
00587 
00588         idx = pmsSz;  /* preSz */
00589         XMEMCPY(md5Input + idx, shaOutput, SHA_DIGEST_SIZE);
00590         idx += SHA_DIGEST_SIZE;
00591         Md5Update(&md5, md5Input, idx);
00592         Md5Final(&md5, &ssl->arrays.masterSecret[i * MD5_DIGEST_SIZE]);
00593     }
00594 
00595 #ifdef SHOW_SECRETS
00596     {
00597         int i;
00598         printf("master secret: ");
00599         for (i = 0; i < SECRET_LEN; i++)
00600             printf("%02x", ssl->arrays.masterSecret[i]);
00601         printf("\n");
00602     }
00603 #endif
00604 
00605     DeriveKeys(ssl);
00606     CleanPreMaster(ssl);
00607 
00608     return 0;
00609 }
00610 
00611 
00612 
00613