-
- if (ctx->protocolSide == kSSLServerSide)
- { serverPending = &ctx->writePending;
- clientPending = &ctx->readPending;
- }
- else
- { serverPending = &ctx->readPending;
- clientPending = &ctx->writePending;
- }
-
- keyDataProgress = key.data;
- memcpy(clientPending->macSecret, keyDataProgress,
- ctx->selectedCipherSpec.macAlgorithm->hash->digestSize);
- keyDataProgress += ctx->selectedCipherSpec.macAlgorithm->hash->digestSize;
- memcpy(serverPending->macSecret, keyDataProgress,
- ctx->selectedCipherSpec.macAlgorithm->hash->digestSize);
- keyDataProgress += ctx->selectedCipherSpec.macAlgorithm->hash->digestSize;
-
- /* init the reusable-per-record MAC contexts */
- err = ctx->sslTslCalls->initMac(clientPending, ctx);
- if(err) {
- goto fail;
- }
- err = ctx->sslTslCalls->initMac(serverPending, ctx);
- if(err) {
- goto fail;
- }
-
- if (ctx->selectedCipherSpec.isExportable == NotExportable)
- { keyPtr = keyDataProgress;
- keyDataProgress += ctx->selectedCipherSpec.cipher->secretKeySize;
- /* Skip server write key to get to IV */
- UInt8 ivSize = ctx->selectedCipherSpec.cipher->ivSize;
-
- if (ivSize == 0)
- {
- ivPtr = NULL;
- }
- else
- {
- ivPtr = keyDataProgress + ctx->selectedCipherSpec.cipher->secretKeySize;
- }
-
- if ((err = ctx->selectedCipherSpec.cipher->initialize(keyPtr, ivPtr,
- clientPending, ctx)) != 0)
- goto fail;
- keyPtr = keyDataProgress;
- keyDataProgress += ctx->selectedCipherSpec.cipher->secretKeySize;
- /* Skip client write IV to get to server write IV */
- if (ivSize == 0)
- {
- ivPtr = NULL;
- }
- else
- {
- ivPtr = keyDataProgress + ctx->selectedCipherSpec.cipher->ivSize;
- }
-
- if ((err = ctx->selectedCipherSpec.cipher->initialize(keyPtr, ivPtr,
- serverPending, ctx)) != 0)
- goto fail;
- }
- else {
- uint8_t clientExportKey[16], serverExportKey[16],
- clientExportIV[16], serverExportIV[16];
- SSLBuffer clientWrite, serverWrite;
- SSLBuffer finalClientWrite, finalServerWrite;
- SSLBuffer finalClientIV, finalServerIV;
-
- assert(ctx->selectedCipherSpec.cipher->keySize <= 16);
- assert(ctx->selectedCipherSpec.cipher->ivSize <= 16);
-
- /* Inputs to generateExportKeyAndIv are clientRandom, serverRandom,
- * clientWriteKey, serverWriteKey. The first two are already present
- * in ctx.
- * Outputs are a key and IV for each of {server, client}.
- */
- clientWrite.data = keyDataProgress;
- clientWrite.length = ctx->selectedCipherSpec.cipher->secretKeySize;
- serverWrite.data = keyDataProgress + clientWrite.length;
- serverWrite.length = ctx->selectedCipherSpec.cipher->secretKeySize;
- finalClientWrite.data = clientExportKey;
- finalServerWrite.data = serverExportKey;
- finalClientIV.data = clientExportIV;
- finalServerIV.data = serverExportIV;
- finalClientWrite.length = 16;
- finalServerWrite.length = 16;
- /* these can be zero */
- finalClientIV.length = ctx->selectedCipherSpec.cipher->ivSize;
- finalServerIV.length = ctx->selectedCipherSpec.cipher->ivSize;
-
- assert(ctx->sslTslCalls != NULL);
- err = ctx->sslTslCalls->generateExportKeyAndIv(ctx, clientWrite, serverWrite,
- finalClientWrite, finalServerWrite, finalClientIV, finalServerIV);
- if(err) {
- goto fail;
- }
- if ((err = ctx->selectedCipherSpec.cipher->initialize(clientExportKey,
- clientExportIV, clientPending, ctx)) != 0)
- goto fail;
- if ((err = ctx->selectedCipherSpec.cipher->initialize(serverExportKey,
- serverExportIV, serverPending, ctx)) != 0)
- goto fail;
- }
-
- /* Ciphers are ready for use */
- ctx->writePending.ready = 1;
- ctx->readPending.ready = 1;
-
- /* Ciphers get swapped by sending or receiving a change cipher spec message */
-
- err = noErr;