diff --git a/cyassl/internal.h b/cyassl/internal.h index e6a6ced27..f93d0bfab 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1261,7 +1261,8 @@ struct CYASSL_CTX { TLSX* extensions; /* RFC 6066 TLS Extensions data */ #endif #ifdef ATOMIC_USER - CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Callback */ + CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Cb */ + CallbackDecryptVerify DecryptVerifyCb; /* Atomic User Decrypt/Verify Cb */ #endif }; @@ -1403,6 +1404,7 @@ typedef struct Keys { #endif word32 encryptSz; /* last size of encrypted data */ + word32 padSz; /* how much to advance after decrypt part */ byte encryptionOn; /* true after change cipher spec */ byte decryptedCur; /* only decrypt current record once */ } Keys; @@ -1826,7 +1828,8 @@ struct CYASSL { #endif CYASSL_ALERT_HISTORY alert_history; #ifdef ATOMIC_USER - void* MacEncryptCtx; /* Atomic User Mac/Encrypt Callback Context */ + void* MacEncryptCtx; /* Atomic User Mac/Encrypt Callback Context */ + void* DecryptVerifyCtx; /* Atomic User Decrypt/Verify Callback Context */ #endif }; diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 5c759219d..d359fd6a4 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -948,6 +948,14 @@ CYASSL_API void CyaSSL_CTX_SetMacEncryptCb(CYASSL_CTX*, CallbackMacEncrypt); CYASSL_API void CyaSSL_SetMacEncryptCtx(CYASSL* ssl, void *ctx); CYASSL_API void* CyaSSL_GetMacEncryptCtx(CYASSL* ssl); +typedef int (*CallbackDecryptVerify)(CYASSL* ssl, + unsigned char* decOut, const unsigned char* decIn, + unsigned int decSz, int content, int verify, unsigned int* padSz, + void* ctx); +CYASSL_API void CyaSSL_CTX_SetDecryptVerifyCb(CYASSL_CTX*, + CallbackDecryptVerify); +CYASSL_API void CyaSSL_SetDecryptVerifyCtx(CYASSL* ssl, void *ctx); +CYASSL_API void* CyaSSL_GetDecryptVerifyCtx(CYASSL* ssl); CYASSL_API const unsigned char* CyaSSL_GetMacSecret(CYASSL*, int); CYASSL_API const unsigned char* CyaSSL_GetClientWriteKey(CYASSL*); @@ -956,9 +964,13 @@ CYASSL_API const unsigned char* CyaSSL_GetServerWriteKey(CYASSL*); CYASSL_API const unsigned char* CyaSSL_GetServerWriteIV(CYASSL*); CYASSL_API int CyaSSL_GetKeySize(CYASSL*); CYASSL_API int CyaSSL_GetSide(CYASSL*); +CYASSL_API int CyaSSL_IsTLSv1_1(CYASSL*); CYASSL_API int CyaSSL_GetBulkCipher(CYASSL*); +CYASSL_API int CyaSSL_GetCipherBlockSize(CYASSL*); +CYASSL_API int CyaSSL_GetAeadMacSize(CYASSL*); CYASSL_API int CyaSSL_GetHmacSize(CYASSL*); CYASSL_API int CyaSSL_GetHmacType(CYASSL*); +CYASSL_API int CyaSSL_GetCipherType(CYASSL*); CYASSL_API int CyaSSL_SetTlsHmacInner(CYASSL*, unsigned char*, unsigned int, int, int); @@ -966,6 +978,9 @@ CYASSL_API int CyaSSL_SetTlsHmacInner(CYASSL*, unsigned char*, enum { CYASSL_SERVER_END = 0, CYASSL_CLIENT_END = 1, + CYASSL_BLOCK_TYPE = 2, + CYASSL_STREAM_TYPE = 3, + CYASSL_AEAD_TYPE = 4, CYASSL_TLS_HMAC_INNER_SZ = 13 /* SEQ_SZ + ENUM + VERSION_SZ + LEN_SZ */ }; diff --git a/cyassl/test.h b/cyassl/test.h index 4635eea9b..a37f05d8b 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -1301,6 +1301,13 @@ typedef struct AtomicEncCtx { } AtomicEncCtx; +/* Atomic Decrypt Context example */ +typedef struct AtomicDecCtx { + int keySetup; /* have we done key setup yet */ + Aes aes; /* for aes example */ +} AtomicDecCtx; + + static INLINE int myMacEncryptCb(CYASSL* ssl, unsigned char* macOut, const unsigned char* macIn, unsigned int macInSz, int macContent, int macVerify, unsigned char* encOut, const unsigned char* encIn, @@ -1360,24 +1367,126 @@ static INLINE int myMacEncryptCb(CYASSL* ssl, unsigned char* macOut, return AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz); } + +static INLINE int myDecryptVerifyCb(CYASSL* ssl, + unsigned char* decOut, const unsigned char* decIn, + unsigned int decSz, int macContent, int macVerify, + unsigned int* padSz, void* ctx) +{ + AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx; + int ret = 0; + int macInSz = 0; + int ivExtra = 0; + int digestSz = CyaSSL_GetHmacSize(ssl); + unsigned int pad = 0; + unsigned int padByte = 0; + Hmac hmac; + byte myInner[CYASSL_TLS_HMAC_INNER_SZ]; + byte verify[INNER_HASH_SIZE]; + const char* tlsStr = "TLS"; + + /* example supports (d)tls aes */ + if (CyaSSL_GetBulkCipher(ssl) != cyassl_aes) { + printf("myMacEncryptCb not using AES\n"); + return -1; + } + + if (strstr(CyaSSL_get_version(ssl), tlsStr) == NULL) { + printf("myMacEncryptCb not using (D)TLS\n"); + return -1; + } + + /*decrypt */ + if (decCtx->keySetup == 0) { + int keyLen = CyaSSL_GetKeySize(ssl); + const byte* key; + const byte* iv; + + /* decrypt is from other side (peer) */ + if (CyaSSL_GetSide(ssl) == CYASSL_SERVER_END) { + key = CyaSSL_GetClientWriteKey(ssl); + iv = CyaSSL_GetClientWriteIV(ssl); + } + else { + key = CyaSSL_GetServerWriteKey(ssl); + iv = CyaSSL_GetServerWriteIV(ssl); + } + + ret = AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION); + if (ret != 0) { + printf("AesSetKey failed in myDecryptVerifyCb\n"); + return ret; + } + decCtx->keySetup = 1; + } + + /* decrypt */ + ret = AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz); + + if (CyaSSL_GetCipherType(ssl) == CYASSL_AEAD_TYPE) { + *padSz = CyaSSL_GetAeadMacSize(ssl); + return 0; /* hmac, not needed if aead mode */ + } + + if (CyaSSL_GetCipherType(ssl) == CYASSL_BLOCK_TYPE) { + pad = *(decOut + decSz - 1); + padByte = 1; + if (CyaSSL_IsTLSv1_1(ssl)) + ivExtra = CyaSSL_GetCipherBlockSize(ssl); + } + + *padSz = CyaSSL_GetHmacSize(ssl) + pad + padByte; + macInSz = decSz - ivExtra - digestSz - pad - padByte; + + CyaSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify); + + HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl), + CyaSSL_GetMacSecret(ssl, macVerify), digestSz); + HmacUpdate(&hmac, myInner, sizeof(myInner)); + HmacUpdate(&hmac, decOut + ivExtra, macInSz); + HmacFinal(&hmac, verify); + + if (memcmp(verify, decOut + decSz - digestSz - pad - padByte, + digestSz) != 0) { + printf("myDecryptVerify verify failed\n"); + return -1; + } + + return ret; +} + + static INLINE void SetupAtomicUser(CYASSL_CTX* ctx, CYASSL* ssl) { AtomicEncCtx* encCtx; + AtomicDecCtx* decCtx; encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx)); if (encCtx == NULL) err_sys("AtomicEncCtx malloc failed"); memset(encCtx, 0, sizeof(AtomicEncCtx)); + decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx)); + if (decCtx == NULL) { + free(encCtx); + err_sys("AtomicDecCtx malloc failed"); + } + memset(decCtx, 0, sizeof(AtomicDecCtx)); + CyaSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb); CyaSSL_SetMacEncryptCtx(ssl, encCtx); + + CyaSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb); + CyaSSL_SetDecryptVerifyCtx(ssl, decCtx); } static INLINE void FreeAtomicUser(CYASSL* ssl) { AtomicEncCtx* encCtx = CyaSSL_GetMacEncryptCtx(ssl); + AtomicDecCtx* decCtx = CyaSSL_GetDecryptVerifyCtx(ssl); + free(decCtx); free(encCtx); } diff --git a/src/internal.c b/src/internal.c index 8070eb79b..85e7abec4 100644 --- a/src/internal.c +++ b/src/internal.c @@ -429,7 +429,8 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method) ctx->extensions = NULL; #endif #ifdef ATOMIC_USER - ctx->MacEncryptCb = NULL; + ctx->MacEncryptCb = NULL; + ctx->DecryptVerifyCb = NULL; #endif if (InitMutex(&ctx->countMutex) < 0) { @@ -1379,6 +1380,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->dtls_msg_list = NULL; #endif ssl->keys.encryptSz = 0; + ssl->keys.padSz = 0; ssl->keys.encryptionOn = 0; /* initially off */ ssl->keys.decryptedCur = 0; /* initially off */ ssl->options.sessionCacheOff = ctx->sessionCacheOff; @@ -1479,7 +1481,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) InitCiphers(ssl); InitCipherSpecs(&ssl->specs); #ifdef ATOMIC_USER - ssl->MacEncryptCtx = NULL; + ssl->MacEncryptCtx = NULL; + ssl->DecryptVerifyCtx = NULL; #endif /* all done with init, now can return errors, call other stuff */ @@ -3366,20 +3369,7 @@ static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx) int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff) { int finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ; - int headerSz = HANDSHAKE_HEADER_SZ; - word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ, - idx = *inOutIdx, - padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz - - ssl->specs.hash_size; - const byte* mac; - - #ifdef CYASSL_DTLS - if (ssl->options.dtls) { - headerSz += DTLS_HANDSHAKE_EXTRA; - macSz += DTLS_HANDSHAKE_EXTRA; - padSz -= DTLS_HANDSHAKE_EXTRA; - } - #endif + word32 idx = *inOutIdx; #ifdef CYASSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo); @@ -3391,32 +3381,9 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff) return VERIFY_FINISHED_ERROR; } } - - if (ssl->specs.cipher_type != aead) { - byte verifyMAC[MAX_DIGEST_SIZE]; - ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz, - handshake, 1); - idx += finishedSz; - - /* read mac and fill */ - mac = input + idx; - idx += ssl->specs.hash_size; - - if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) - padSz -= ssl->specs.block_size; - - idx += padSz; - - /* verify mac */ - if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size) != 0) { - CYASSL_MSG("Verify finished error on mac"); - return VERIFY_MAC_ERROR; - } - } - else { - idx += (finishedSz + ssl->specs.aead_mac_size); - } - + idx += finishedSz; + idx += ssl->keys.padSz; + if (ssl->options.side == CYASSL_CLIENT_END) { ssl->options.serverState = SERVER_FINISHED_COMPLETE; if (!ssl->options.resuming) { @@ -3865,6 +3832,7 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) } + static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, word32 sz) { @@ -4035,32 +4003,6 @@ static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz) } -/* decrypt input message in place */ -static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx) -{ - int decryptResult; - int sanityResult = SanityCheckCipherText(ssl, sz); - - if (sanityResult != 0) - return sanityResult; - - decryptResult = Decrypt(ssl, input, input, sz); - - if (decryptResult == 0) - { - ssl->keys.encryptSz = sz; - ssl->keys.decryptedCur = 1; - - if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) - *idx += ssl->specs.block_size; /* go past TLSv1.1 IV */ - if (ssl->specs.cipher_type == aead) - *idx += AEAD_EXP_IV_SZ; - } - - return decryptResult; -} - - #ifndef NO_OLD_TLS static INLINE void Md5Rounds(int rounds, const byte* data, int sz) @@ -4284,7 +4226,7 @@ static INLINE int GetRounds(int pLen, int padLen, int t) /* timing resistant pad/verify check, return 0 on success */ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t, - int pLen) + int pLen, int content) { byte verify[MAX_DIGEST_SIZE]; byte dummy[MAX_PAD_SIZE]; @@ -4294,7 +4236,7 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t, if ( (t + padLen + 1) > pLen) { CYASSL_MSG("Plain Len not long enough for pad/mac"); PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE); - ssl->hmac(ssl, verify, input, pLen - t, application_data, 1); + ssl->hmac(ssl, verify, input, pLen - t, content, 1); ConstantCompare(verify, input + pLen - t, t); return VERIFY_MAC_ERROR; @@ -4303,14 +4245,14 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t, if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) { CYASSL_MSG("PadCheck failed"); PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1); - ssl->hmac(ssl, verify, input, pLen - t, application_data, 1); + ssl->hmac(ssl, verify, input, pLen - t, content, 1); ConstantCompare(verify, input + pLen - t, t); return VERIFY_MAC_ERROR; } PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1); - ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, application_data, 1); + ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1); CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy); @@ -4326,17 +4268,13 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t, int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx) { word32 msgSz = ssl->keys.encryptSz; - word32 pad = 0, - padByte = 0, - idx = *inOutIdx, - digestSz = ssl->specs.hash_size; - int dataSz, ret; + word32 idx = *inOutIdx; + int dataSz; int ivExtra = 0; byte* rawData = input + idx; /* keep current for hmac */ #ifdef HAVE_LIBZ byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA]; #endif - byte verify[MAX_DIGEST_SIZE]; if (ssl->options.handShakeState != HANDSHAKE_DONE) { CYASSL_MSG("Received App data before handshake complete"); @@ -4347,35 +4285,12 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx) if (ssl->specs.cipher_type == block) { if (ssl->options.tls1_1) ivExtra = ssl->specs.block_size; - pad = *(input + idx + msgSz - ivExtra - 1); - padByte = 1; - - if (ssl->options.tls) { - ret = TimingPadVerify(ssl, input + idx, pad, digestSz, - msgSz - ivExtra); - if (ret != 0) - return ret; - } - else { /* sslv3, some implementations have bad padding */ - ssl->hmac(ssl, verify, rawData, msgSz - digestSz - pad - 1, - application_data, 1); - if (ConstantCompare(verify, rawData + msgSz - digestSz - pad - 1, - digestSz) != 0) - return VERIFY_MAC_ERROR; - } - } - else if (ssl->specs.cipher_type == stream) { - ssl->hmac(ssl, verify, rawData, msgSz - digestSz, application_data, 1); - if (ConstantCompare(verify, rawData + msgSz - digestSz, digestSz) != 0){ - return VERIFY_MAC_ERROR; - } } else if (ssl->specs.cipher_type == aead) { ivExtra = AEAD_EXP_IV_SZ; - digestSz = ssl->specs.aead_mac_size; } - dataSz = msgSz - ivExtra - digestSz - pad - padByte; + dataSz = msgSz - ivExtra - ssl->keys.padSz; if (dataSz < 0) { CYASSL_MSG("App data buffer error, malicious input?"); return BUFFER_ERROR; @@ -4397,10 +4312,7 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx) ssl->buffers.clearOutputBuffer.length = dataSz; } - idx += digestSz; - idx += pad; - if (padByte) - idx++; + idx += ssl->keys.padSz; #ifdef HAVE_LIBZ /* decompress could be bigger, overwrite after verify */ @@ -4444,27 +4356,7 @@ static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type) CYASSL_ERROR(*type); if (ssl->keys.encryptionOn) { - if (ssl->specs.cipher_type != aead) { - int aSz = ALERT_SIZE; - const byte* mac; - byte verify[MAX_DIGEST_SIZE]; - int padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size; - - ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1); - - /* read mac and fill */ - mac = input + *inOutIdx; - *inOutIdx += (ssl->specs.hash_size + padSz); - - /* verify */ - if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) { - CYASSL_MSG(" alert verify mac error"); - return VERIFY_MAC_ERROR; - } - } - else { - *inOutIdx += ssl->specs.aead_mac_size; - } + *inOutIdx += ssl->keys.padSz; } return level; @@ -4533,11 +4425,61 @@ static int GetInputData(CYASSL *ssl, word32 size) return 0; } + +static INLINE int VerifyMac(CYASSL* ssl, const byte* input, word32 msgSz, + int content, word32* padSz) +{ + int ivExtra = 0; + int ret; + word32 pad = 0; + word32 padByte = 0; + word32 digestSz = ssl->specs.hash_size; + byte verify[MAX_DIGEST_SIZE]; + + if (ssl->specs.cipher_type == block) { + if (ssl->options.tls1_1) + ivExtra = ssl->specs.block_size; + pad = *(input + msgSz - ivExtra - 1); + padByte = 1; + + if (ssl->options.tls) { + ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra, + content); + if (ret != 0) + return ret; + } + else { /* sslv3, some implementations have bad padding */ + ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1, + content, 1); + if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1, + digestSz) != 0) + return VERIFY_MAC_ERROR; + } + } + else if (ssl->specs.cipher_type == stream) { + ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1); + if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){ + return VERIFY_MAC_ERROR; + } + } + + if (ssl->specs.cipher_type == aead) { + *padSz = ssl->specs.aead_mac_size; + } + else { + *padSz = digestSz + pad + padByte; + } + + return 0; +} + + /* process input requests, return 0 is done, 1 is call again to complete, and negative number is error */ int ProcessReply(CYASSL* ssl) { int ret = 0, type, readSz; + int atomicUser = 0; word32 startIdx = 0; #ifndef NO_CYASSL_SERVER byte b0, b1; @@ -4546,6 +4488,11 @@ int ProcessReply(CYASSL* ssl) int used; #endif +#ifdef ATOMIC_USER + if (ssl->ctx->DecryptVerifyCb) + atomicUser = 1; +#endif + for (;;) { switch ((processReply)ssl->options.processReply) { @@ -4676,14 +4623,53 @@ int ProcessReply(CYASSL* ssl) case runProcessingOneMessage: if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0) { - ret = DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer + - ssl->buffers.inputBuffer.idx, - ssl->curSize, - &ssl->buffers.inputBuffer.idx); + ret = SanityCheckCipherText(ssl, ssl->curSize); + if (ret < 0) + return ret; + + if (atomicUser) { + #ifdef ATOMIC_USER + ret = ssl->ctx->DecryptVerifyCb(ssl, + ssl->buffers.inputBuffer.buffer + + ssl->buffers.inputBuffer.idx, + ssl->buffers.inputBuffer.buffer + + ssl->buffers.inputBuffer.idx, + ssl->curSize, ssl->curRL.type, 1, + &ssl->keys.padSz, ssl->DecryptVerifyCtx); + if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) + ssl->buffers.inputBuffer.idx += ssl->specs.block_size; + /* go past TLSv1.1 IV */ + if (ssl->specs.cipher_type == aead) + ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ; + #endif /* ATOMIC_USER */ + } + else { + ret = Decrypt(ssl, ssl->buffers.inputBuffer.buffer + + ssl->buffers.inputBuffer.idx, + ssl->buffers.inputBuffer.buffer + + ssl->buffers.inputBuffer.idx, + ssl->curSize); + if (ret < 0) { + CYASSL_ERROR(ret); + return DECRYPT_ERROR; + } + if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) + ssl->buffers.inputBuffer.idx += ssl->specs.block_size; + /* go past TLSv1.1 IV */ + if (ssl->specs.cipher_type == aead) + ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ; + + ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer + + ssl->buffers.inputBuffer.idx, + ssl->curSize, ssl->curRL.type, + &ssl->keys.padSz); + } if (ret < 0) { CYASSL_ERROR(ret); return DECRYPT_ERROR; } + ssl->keys.encryptSz = ssl->curSize; + ssl->keys.decryptedCur = 1; } CYASSL_MSG("received record layer msg"); diff --git a/src/ssl.c b/src/ssl.c index 089fe2297..0374d5c41 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -830,6 +830,29 @@ void* CyaSSL_GetMacEncryptCtx(CYASSL* ssl) } +void CyaSSL_CTX_SetDecryptVerifyCb(CYASSL_CTX* ctx, CallbackDecryptVerify cb) +{ + if (ctx) + ctx->DecryptVerifyCb = cb; +} + + +void CyaSSL_SetDecryptVerifyCtx(CYASSL* ssl, void *ctx) +{ + if (ssl) + ssl->DecryptVerifyCtx = ctx; +} + + +void* CyaSSL_GetDecryptVerifyCtx(CYASSL* ssl) +{ + if (ssl) + return ssl->DecryptVerifyCtx; + + return NULL; +} + + const byte* CyaSSL_GetClientWriteKey(CYASSL* ssl) { if (ssl) @@ -884,6 +907,52 @@ int CyaSSL_GetBulkCipher(CYASSL* ssl) } +int CyaSSL_GetCipherType(CYASSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + if (ssl->specs.cipher_type == block) + return CYASSL_BLOCK_TYPE; + if (ssl->specs.cipher_type == stream) + return CYASSL_STREAM_TYPE; + if (ssl->specs.cipher_type == aead) + return CYASSL_AEAD_TYPE; + + return -1; +} + + +int CyaSSL_GetCipherBlockSize(CYASSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + return ssl->specs.block_size; +} + + +int CyaSSL_GetAeadMacSize(CYASSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + return ssl->specs.aead_mac_size; +} + + +int CyaSSL_IsTLSv1_1(CYASSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + if (ssl->options.tls1_1) + return 1; + + return 0; +} + + int CyaSSL_GetSide(CYASSL* ssl) { if (ssl)