void psSha512Update(psDigestContext_t *md, const unsigned char *buf, uint32 len) { uint32 n; psAssert(md != NULL); psAssert(buf != NULL); while (len > 0) { if (md->sha512.curlen == 0 && len >= 128) { sha512_compress(md, (unsigned char *)buf); md->sha512.length += 1024; buf += 128; len -= 128; } else { n = min(len, (128 - md->sha512.curlen)); memcpy(md->sha512.buf + md->sha512.curlen, buf, (size_t)n); md->sha512.curlen += n; buf += n; len -= n; if (md->sha512.curlen == 128) { sha512_compress (md, md->sha512.buf); md->sha512.length += 1024; md->sha512.curlen = 0; } } } return; }
int32_t psMd2Update(psMd2_t *md, const unsigned char *buf, uint32_t len) { uint32_t n; # ifdef CRYPTO_ASSERT psAssert(md != NULL); psAssert(buf != NULL); if (md->curlen > sizeof(md->buf)) { psTraceCrypto("psMd2Update error\n"); return PS_LIMIT_FAIL; } # endif while (len > 0) { n = min(len, (16 - md->curlen)); memcpy(md->buf + md->curlen, buf, (size_t) n); md->curlen += n; buf += n; len -= n; /* is 16 bytes full? */ if (md->curlen == 16) { md2_compress(md); md2_update_chksum(md); md->curlen = 0; } } return PS_SUCCESS; }
int32 psMd2Final(psDigestContext_t * md, unsigned char *hash) { uint32 i, k; psAssert(md != NULL); psAssert(hash != NULL); if (md->md2.curlen >= sizeof(md->md2.buf)) { psTraceCrypto("psMd2Final error\n"); return PS_LIMIT_FAIL; } /* pad the message */ k = 16 - md->md2.curlen; for (i = md->md2.curlen; i < 16; i++) { md->md2.buf[i] = (unsigned char)k; } /* hash and update */ md2_compress(md); md2_update_chksum(md); /* hash checksum */ memcpy(md->md2.buf, md->md2.chksum, 16); md2_compress(md); /* output is lower 16 bytes of X */ memcpy(hash, md->md2.X, 16); memset(md, 0x0, sizeof(psDigestContext_t)); return PS_SUCCESS; }
void psMd4Update(psDigestContext_t * md, const unsigned char *buf, uint32 len) { uint32 n; psAssert(md != NULL); psAssert(buf != NULL); while (len > 0) { n = min(len, (64 - md->md4.curlen)); memcpy(md->md4.buf + md->md4.curlen, buf, (size_t)n); md->md4.curlen += n; buf += n; len -= n; /* is 64 bytes full? */ if (md->md4.curlen == 64) { md4_compress(md, md->md4.buf); #ifdef HAVE_NATIVE_INT64 md->md4.length += 512; #else n = (md->md4.lengthLo + 512) & 0xFFFFFFFFL; if (n < md->md4.lengthLo) { md->md4.lengthHi++; } md->md4.lengthLo = n; #endif /* HAVE_NATIVE_INT64 */ md->md4.curlen = 0; } } }
int32 psMd2Update(psDigestContext_t *md, const unsigned char *buf, uint32 len) { uint32 n; psAssert(md != NULL); psAssert(buf != NULL); if (md->md2.curlen > sizeof(md->md2.buf)) { psTraceCrypto("psMd2Update error\n"); return PS_LIMIT_FAIL; } while (len > 0) { n = min(len, (16 - md->md2.curlen)); memcpy(md->md2.buf + md->md2.curlen, buf, (size_t)n); md->md2.curlen += n; buf += n; len -= n; /* is 16 bytes full? */ if (md->md2.curlen == 16) { md2_compress(md); md2_update_chksum(md); md->md2.curlen = 0; } } return PS_SUCCESS; }
/* Initialize psChacha20Poly1305Ietf for use. */ psRes_t psChacha20Poly1305IetfInit( psChacha20Poly1305Ietf_t *ctx, const unsigned char key[PS_EXACTLY(PS_CHACHA20POLY1305_IETF_KEYBYTES)]) { /* Ensure constants match. */ static int pschacha2_initialized = 0; if (!pschacha2_initialized) { extern int psCrypto_stream_chacha20_pick_best_implementation(void); extern int psCrypto_onetimeauth_poly1305_pick_best_implementation(void); extern int psSodium_runtime_get_cpu_features(void); psAssert(crypto_aead_chacha20poly1305_ietf_KEYBYTES == PS_CHACHA20POLY1305_IETF_KEYBYTES); psAssert(crypto_aead_chacha20poly1305_IETF_NPUBBYTES == PS_CHACHA20POLY1305_IETF_NPUBBYTES); psAssert(crypto_aead_chacha20poly1305_ietf_ABYTES == PS_CHACHA20POLY1305_IETF_ABYTES); if (!getenv("MATRIX_CHACHA20POLY1305_REF")) { (void)psSodium_runtime_get_cpu_features(); (void)psCrypto_stream_chacha20_pick_best_implementation(); (void)psCrypto_onetimeauth_poly1305_pick_best_implementation(); } pschacha2_initialized = 1; } /* Copy the key */ memcpy(ctx->key, key, PS_CHACHA20POLY1305_IETF_KEYBYTES); return PS_SUCCESS; }
/* Encode (encrypt) 'len' bytes of plaintext data that has been placed into the buffer given by matrixSslGetWritebuf(). This is an in-situ encode. CAN ONLY BE CALLED AFTER A PREVIOUS CALL TO matrixSslGetWritebuf len >= 0.If len is zero, we send out a blank ssl record len must be <= size returned by matrixSslGetWritebuf() Returns < 0 on error, total #bytes in outgoing data buf on success */ int32 matrixSslEncodeWritebuf(ssl_t *ssl, uint32 len) { unsigned char *origbuf; int32 rc, reserved; if (!ssl || ((int32)len < 0)) { return PS_ARG_FAIL; } if (ssl->bFlags & BFLAG_CLOSE_AFTER_SENT) { return PS_PROTOCOL_FAIL; } psAssert(ssl->outsize > 0 && ssl->outbuf != NULL); /* Caller was given proper locations and lengths in GetWritebuf() */ origbuf = ssl->outbuf + ssl->outlen; if (ssl->outbuf == NULL || (ssl->outsize - ssl->outlen) < (int32)len) { return PS_FAILURE; } reserved = ssl->recordHeadLen; #ifdef USE_BEAST_WORKAROUND if (ssl->bFlags & BFLAG_STOP_BEAST) { rc = ((ssl->enMacSize + 1) % ssl->enBlockSize) ? ssl->enBlockSize : 0; reserved += ssl->recordHeadLen + rc + (ssl->enBlockSize * ((ssl->enMacSize + 1)/ssl->enBlockSize)) - 1; } #endif #ifdef USE_TLS_1_1 /* If a block cipher is being used TLS 1.1 requires the use of an explicit IV. This is an extra random block of data prepended to the plaintext before encryption. Account for that extra length here. */ if ((ssl->flags & SSL_FLAGS_WRITE_SECURE) && (ssl->flags & SSL_FLAGS_TLS_1_1) && (ssl->enBlockSize > 1)) { reserved += ssl->enBlockSize; } #if defined(USE_TLS_1_2) && defined(USE_AES_GCM) if ((ssl->flags & SSL_FLAGS_TLS_1_2) && (ssl->flags & SSL_FLAGS_GMAC_W)) { reserved += ssl->nonceCtrLen; } #endif /* USE_TLS_1_2 && AES_GCM */ #endif /* USE_TLS_1_1 */ rc = matrixSslEncode(ssl, origbuf, (ssl->outsize - ssl->outlen), origbuf + reserved, &len); if (rc < 0) { psAssert(rc != SSL_FULL); /* should not happen */ return PS_FAILURE; } #ifdef USE_MATRIXSSL_STATS matrixsslUpdateStat(ssl, APP_DATA_SENT_STAT, len); #endif ssl->outlen += len; return ssl->outlen; }
/* This public API allows the user to encrypt the plaintext buffer of their choice into the internal outbuf that is retrieved when matrixSslGetOutdata is called. This is non-in-situ support and will leave the callers plaintext buffer intact ptBuf The plaintext buffer to be converted into an SSL application data record. len The length, in bytes, of the ptBuf plaintext data Returns < 0 on error, total #bytes in outgoing data buf on success */ int32 matrixSslEncodeToOutdata(ssl_t *ssl, unsigned char *ptBuf, uint32 len) { unsigned char *internalBuf; int32 rc, fragLen, recLen, index; if (!ssl || !ptBuf) { return PS_ARG_FAIL; } if (ssl->bFlags & BFLAG_CLOSE_AFTER_SENT) { return PS_PROTOCOL_FAIL; } #ifdef USE_DTLS if (ssl->flags & SSL_FLAGS_DTLS) { rc = matrixSslGetEncodedSize(ssl, len); if (rc > matrixDtlsGetPmtu()) { return PS_LIMIT_FAIL; } } #endif /* Fragmentation support */ index = 0; while (len > 0) { /* We just call matrixSslGetWritebuf to prepare the buffer */ if ((rc = matrixSslGetWritebuf(ssl, &internalBuf, len)) < 0) { psTraceIntInfo("matrixSslEncodeToOutbuf allocation error: %d\n", rc); return rc; } recLen = fragLen = min((uint32)rc, len); psAssert(ssl->outsize > 0 && ssl->outbuf != NULL); if (ssl->outbuf == NULL || (ssl->outsize - ssl->outlen) < (int32)fragLen) { return PS_FAILURE; } internalBuf = ssl->outbuf + ssl->outlen; rc = matrixSslEncode(ssl, internalBuf, (ssl->outsize - ssl->outlen), ptBuf + index, (uint32*)&fragLen); if (rc < 0) { psAssert(rc != SSL_FULL); /* should not happen */ return PS_FAILURE; } index += recLen; len -= recLen; #ifdef USE_MATRIXSSL_STATS matrixsslUpdateStat(ssl, APP_DATA_SENT_STAT, fragLen); #endif ssl->outlen += fragLen; } return ssl->outlen; }
void psAesEncryptCBC(psAesCbc_t *ctx, const unsigned char *pt, unsigned char *ct, uint32_t len) { int outl = len; if (!EVP_EncryptUpdate(ctx, ct, &outl, pt, len)) { EVP_CIPHER_CTX_cleanup(ctx); psAssert(0); } psAssert(outl == len); }
void psSha224Final(psSha256_t *sha256, unsigned char out[SHA224_HASHLEN]) { unsigned char buf[SHA224_HASHLEN]; #ifdef CRYPTO_ASSERT psAssert(sha256 != NULL); psAssert(out != NULL); #endif psSha256Final(sha256, buf); memcpy(out, buf, SHA224_HASH_SIZE); #ifdef USE_BURN_STACK psBurnStack(sizeof(buf)); #endif }
int32 psSha512Final(psDigestContext_t * md, unsigned char *out) { int i; psAssert(md != NULL); psAssert(out != NULL); if (md->sha512.curlen >= sizeof(md->sha512.buf)) { return PS_ARG_FAIL; } /* increase the length of the message */ md->sha512.length += md->sha512.curlen * CONST64(8); /* append the '1' bit */ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80; /* if the length is currently above 112 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->sha512.curlen > 112) { while (md->sha512.curlen < 128) { md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; } sha512_compress(md, md->sha512.buf); md->sha512.curlen = 0; } /* pad upto 120 bytes of zeroes * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash * > 2^64 bits of data... :-) */ while (md->sha512.curlen < 120) { md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; } /* store length */ STORE64H(md->sha512.length, md->sha512.buf+120); sha512_compress(md, md->sha512.buf); /* copy output */ for (i = 0; i < 8; i++) { STORE64H(md->sha512.state[i], out+(8*i)); } #ifdef USE_BURN_STACK psBurnStack(sizeof(psDigestContext_t)); #endif return SHA512_HASH_SIZE; }
int32 psSha224Final(psDigestContext_t *md, unsigned char *out) { unsigned char buf[32]; int32 err; psAssert(md != NULL); psAssert(out != NULL); err = psSha256Final(md, buf); memcpy(out, buf, SHA224_HASH_SIZE); #ifdef USE_BURN_STACK psBurnStack(sizeof(buf)); #endif return err; }
void psHmacSha2Init(psHmacContext_t *ctx, unsigned char *key, uint32 keyLen, uint32 hashSize) { int32 i, padLen = 64; #ifdef USE_SHA384 if (hashSize == SHA384_HASH_SIZE) { padLen = 128; } #endif psAssert(keyLen <= (uint32)padLen); for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x36; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x36; } if (hashSize == SHA384_HASH_SIZE) { #ifdef USE_SHA384 psSha384Init(&ctx->u.sha512); psSha384Update(&ctx->u.sha512, ctx->pad, padLen); #endif } else { psSha256Init(&ctx->u.sha256); psSha256Update(&ctx->u.sha256, ctx->pad, padLen); } for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x5c; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x5c; } }
/* Plaintext data has been processed as a response to MATRIXSSL_APP_DATA or MATRIXSSL_RECEIVED_ALERT return codes from matrixSslReceivedData() Return: < 0 on error 0 if there is no more incoming ssl data in the buffer Caller should take whatever action is appropriate to the specific protocol implementation, eg. read for more data, close, etc. > 0 error code is same meaning as from matrixSslReceivedData() In this case, ptbuf and ptlen will be modified and caller should handle return code identically as from matrixSslReceivedData() This is the case when more than one SSL record is in the buffer */ int32 matrixSslProcessedData(ssl_t *ssl, unsigned char **ptbuf, uint32 *ptlen) { uint32 ctlen; if (!ssl || !ptbuf || !ptlen) { return PS_ARG_FAIL; } *ptbuf = NULL; *ptlen = 0; psAssert(ssl->insize > 0 && ssl->inbuf != NULL); /* Move any remaining data to the beginning of the buffer */ if (ssl->inlen > 0) { ctlen = ssl->rec.len + ssl->recordHeadLen; if (ssl->flags & SSL_FLAGS_AEAD_R) { /* This overhead was removed from rec.len after the decryption to keep buffer logic working. */ /* TODO: This is for checking async or not. If async, this length tweak never happens. Need a more generic way to look for blocking or not */ ctlen += AEAD_TAG_LEN(ssl) + AEAD_NONCE_LEN(ssl); } memmove(ssl->inbuf, ssl->inbuf + ctlen, ssl->inlen); } /* Shrink inbuf to default size once inlen < default size */ revertToDefaultBufsize(ssl, SSL_INBUF); /* If there's more data, try to decode it here and return that code */ if (ssl->inlen > 0) { /* NOTE: ReceivedData cannot return 0 */ return matrixSslReceivedData(ssl, 0, ptbuf, ptlen); } return MATRIXSSL_SUCCESS; }
/* Plaintext data has been processed as a response to MATRIXSSL_APP_DATA or MATRIXSSL_RECEIVED_ALERT return codes from matrixSslReceivedData() Return: < 0 on error 0 if there is no more incoming ssl data in the buffer Caller should take whatever action is appropriate to the specific protocol implementation, eg. read for more data, close, etc. > 0 error code is same meaning as from matrixSslReceivedData() In this case, ptbuf and ptlen will be modified and caller should handle return code identically as from matrixSslReceivedData() This is the case when more than one SSL record is in the buffer */ int32 matrixSslProcessedData(ssl_t *ssl, unsigned char **ptbuf, uint32 *ptlen) { uint32 ctlen; if (!ssl || !ptbuf || !ptlen) { return PS_ARG_FAIL; } *ptbuf = NULL; *ptlen = 0; psAssert(ssl->insize > 0 && ssl->inbuf != NULL); /* Move any remaining data to the beginning of the buffer */ if (ssl->inlen > 0) { ctlen = ssl->rec.len + ssl->recordHeadLen; #if defined(USE_TLS_1_2) && defined(USE_AES_GCM) if (ssl->flags & SSL_FLAGS_GMAC_R) { /* This overhead was removed from rec.len after the decryption to keep buffer logic working. */ ctlen += TLS_GCM_TAG_LEN + ssl->nonceCtrLen; } #endif memmove(ssl->inbuf, ssl->inbuf + ctlen, ssl->inlen); } /* Shrink inbuf to default size once inlen < default size */ revertToDefaultBufsize(ssl, SSL_INBUF); /* If there's more data, try to decode it here and return that code */ if (ssl->inlen > 0) { /* NOTE: ReceivedData cannot return 0 */ return matrixSslReceivedData(ssl, 0, ptbuf, ptlen); } return MATRIXSSL_SUCCESS; }
void psHmacSha1Update(psHmacContext_t *ctx, const unsigned char *buf, uint32 len) { psAssert(ctx != NULL && buf != NULL); psSha1Update(&ctx->u.sha1, buf, len); }
int32 psHmacSha2Final(psHmacContext_t *ctx, unsigned char *hash, uint32 hashSize) { psAssert(ctx != NULL); if (hash == NULL) { psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n"); return PS_ARG_FAIL; } if (hashSize == SHA384_HASH_SIZE) { #ifdef USE_SHA384 psSha384Final(&ctx->u.sha512, hash); psSha384Init(&ctx->u.sha512); psSha384Update(&ctx->u.sha512, ctx->pad, 128); psSha384Update(&ctx->u.sha512, hash, SHA384_HASH_SIZE); psSha384Final(&ctx->u.sha512, hash); #else return PS_UNSUPPORTED_FAIL; #endif } else { psSha256Final(&ctx->u.sha256, hash); psSha256Init(&ctx->u.sha256); psSha256Update(&ctx->u.sha256, ctx->pad, 64); psSha256Update(&ctx->u.sha256, hash, SHA256_HASH_SIZE); psSha256Final(&ctx->u.sha256, hash); } memset(ctx->pad, 0x0, sizeof(ctx->pad)); return hashSize; }
/* Psuedo-random function. TLS uses this for key generation and hashing */ int32_t prf(const unsigned char *sec, uint16_t secLen, const unsigned char *seed, uint16_t seedLen, unsigned char *out, uint16_t outLen) { const unsigned char *s1, *s2; unsigned char md5out[SSL_MAX_KEY_BLOCK_SIZE]; unsigned char sha1out[SSL_MAX_KEY_BLOCK_SIZE]; int32_t rc = PS_FAIL; uint16_t sLen, i; psAssert(outLen <= SSL_MAX_KEY_BLOCK_SIZE); sLen = (secLen / 2) + (secLen % 2); s1 = sec; s2 = (sec + sLen) - (secLen % 2); if ((rc = pMd5(s1, sLen, seed, seedLen, md5out, outLen)) < 0) { goto L_RETURN; } if ((rc = pSha1(s2, sLen, seed, seedLen, sha1out, outLen)) < 0) { goto L_RETURN; } for (i = 0; i < outLen; i++) { out[i] = md5out[i] ^ sha1out[i]; } rc = outLen; L_RETURN: memzero_s(md5out, SSL_MAX_KEY_BLOCK_SIZE); memzero_s(sha1out, SSL_MAX_KEY_BLOCK_SIZE); return rc; }
/* Just does the GCM decrypt portion. Doesn't expect the tag to be at the end of the ct. User will invoke psAesGetGCMTag seperately */ void psAesDecryptGCMtagless(psAesGcm_t *ctx, const unsigned char *ct, unsigned char *pt, uint32_t len) { /* Not possible with libsodium ? */ psAssert(0); }
int32_t psHmacSha384Init(psHmacSha384_t *ctx, const unsigned char *key, uint16_t keyLen) { int32_t rc, i, padLen; padLen = 128; #ifdef CRYPTO_ASSERT psAssert(keyLen <= (uint32)padLen); #endif for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x36; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x36; } if ((rc = psSha384Init(&ctx->sha384)) < 0) { return rc; } psSha384Update(&ctx->sha384, ctx->pad, padLen); for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x5c; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x5c; } return PS_SUCCESS; }
/* Close a socket and free associated SSL context and buffers */ static void closeConn(httpConn_t *cp, int32 reason) { unsigned char *buf; int32 len; DLListRemove(&cp->List); /* Quick attempt to send a closure alert, don't worry about failure */ if (matrixSslEncodeClosureAlert(cp->ssl) >= 0) { if ((len = matrixSslGetOutdata(cp->ssl, &buf)) > 0) { if ((len = send(cp->fd, buf, len, MSG_DONTWAIT)) > 0) { matrixSslSentData(cp->ssl, len); } } } if (cp->parsebuf != NULL) { psAssert(cp->parsebuflen > 0); free(cp->parsebuf); cp->parsebuflen = 0; } matrixSslDeleteSession(cp->ssl); if (cp->fd != INVALID_SOCKET) { close(cp->fd); } if (reason >= 0) { /* _psTraceInt("=== Closing Client %d ===\n", cp->fd); */ } else { _psTraceInt("=== Closing Client %d on Error ===\n", cp->fd); } free(cp); }
/* Get the BIT STRING key and plug into RSA structure. */ int32 getAsnRsaPubKey(psPool_t *pool, unsigned char **pp, uint32 len, psRsaKey_t *pubKey) { unsigned char *p = *pp; uint32 pubKeyLen, seqLen; int32 ignore_bits; memset(pubKey, 0x0, sizeof(psRsaKey_t)); if (len < 1 || (*(p++) != ASN_BIT_STRING) || getAsnLength(&p, len - 1, &pubKeyLen) < 0 || (len - 1) < pubKeyLen) { psTraceCrypto("Initial parse error in getAsnRsaPubKey\n"); return PS_PARSE_FAIL; } ignore_bits = *p++; /* We assume this is always zero */ psAssert(ignore_bits == 0); if (getAsnSequence(&p, pubKeyLen, &seqLen) < 0 || getAsnBig(pool, &p, seqLen, &pubKey->N) < 0 || getAsnBig(pool, &p, seqLen, &pubKey->e) < 0) { psTraceCrypto("Secondary parse error in getAsnRsaPubKey\n"); return PS_PARSE_FAIL; } pubKey->size = pstm_unsigned_bin_size(&pubKey->N); *pp = p; return PS_SUCCESS; }
int32_t psHmacSha1Init(psHmacSha1_t *ctx, const unsigned char *key, uint16_t keyLen) { int32_t rc, i; #ifdef CRYPTO_ASSERT psAssert(keyLen <= 64); #endif for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x36; } for (i = keyLen; (uint32)i < 64; i++) { ctx->pad[i] = 0x36; } if ((rc = psSha1Init(&ctx->sha1)) < 0) { return rc; } psSha1Update(&ctx->sha1, ctx->pad, 64); for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x5c; } for (i = keyLen; i < 64; i++) { ctx->pad[i] = 0x5c; } return PS_SUCCESS; }
void psSha256Update(psSha256_t *sha256, const unsigned char *buf, uint32_t len) { uint32 n; #ifdef CRYPTO_ASSERT psAssert(sha256 != NULL); psAssert(buf != NULL); #endif while (len > 0) { if (sha256->curlen == 0 && len >= 64) { sha256_compress(sha256, (unsigned char *)buf); #ifdef HAVE_NATIVE_INT64 sha256->length += 512; #else n = (sha256->lengthLo + 512) & 0xFFFFFFFFL; if (n < sha256->lengthLo) { sha256->lengthHi++; } sha256->lengthLo = n; #endif /* HAVE_NATIVE_INT64 */ buf += 64; len -= 64; } else { n = min(len, (64 - sha256->curlen)); memcpy(sha256->buf + sha256->curlen, buf, (size_t)n); sha256->curlen += n; buf += n; len -= n; if (sha256->curlen == 64) { sha256_compress (sha256, sha256->buf); #ifdef HAVE_NATIVE_INT64 sha256->length += 512; #else n = (sha256->lengthLo + 512) & 0xFFFFFFFFL; if (n < sha256->lengthLo) { sha256->lengthHi++; } sha256->lengthLo = n; #endif /* HAVE_NATIVE_INT64 */ sha256->curlen = 0; } } } return; }
int32 matrixSslNewServerSession(ssl_t **ssl, const sslKeys_t *keys, sslCertCb_t certCb, sslSessOpts_t *options) { ssl_t *lssl; if (!ssl) { return PS_ARG_FAIL; } if (options == NULL) { return PS_ARG_FAIL; } /* Add SERVER_FLAGS to versionFlag member of options */ options->versionFlag |= SSL_FLAGS_SERVER; *ssl = NULL; lssl = NULL; #ifdef USE_CLIENT_AUTH if (certCb) { options->versionFlag |= SSL_FLAGS_CLIENT_AUTH; if (matrixSslNewSession(&lssl, keys, NULL, options) < 0) { goto NEW_SVR_ERROR; } matrixSslSetCertValidator(lssl, (sslCertCb_t)certCb); } else if (matrixSslNewSession(&lssl, keys, NULL, options) < 0) { goto NEW_SVR_ERROR; } #else psAssert(certCb == NULL); if (matrixSslNewSession(&lssl, keys, NULL, options) < 0) { goto NEW_SVR_ERROR; } #endif /* USE_CLIENT_AUTH */ lssl->userPtr = options->userPtr; if (options->maxFragLen < 0) { /* User wants to deny a client request for changing max frag len */ lssl->extFlags.deny_max_fragment_len = 1; } lssl->maxPtFrag = SSL_MAX_PLAINTEXT_LEN; if (options->truncHmac < 0) { lssl->extFlags.deny_truncated_hmac = 1; } /* Extended master secret is enabled by default. If user sets to 1 this is a flag to REQUIRE its use */ if (options->extendedMasterSecret > 0) { lssl->extFlags.require_extended_master_secret = 1; } *ssl = lssl; return MATRIXSSL_SUCCESS; NEW_SVR_ERROR: if (lssl) matrixSslDeleteSession(lssl); return PS_FAILURE; }
void psHmacSha384Final(psHmacSha384_t *ctx, unsigned char hash[SHA384_HASHLEN]) { if (HMAC_Final(ctx, hash, NULL) != 1) { psAssert(0); } HMAC_CTX_cleanup(ctx); }
/** Finalize output of the combined MD5-SHA1 The output is 36 bytes, first the 16 bytes MD5 then the 20 bytes SHA1 */ void psMd5Sha1Final(psMd5Sha1_t *md, unsigned char hash[MD5SHA1_HASHLEN]) { # ifdef CRYPTO_ASSERT psAssert(md && hash); # endif psMd5Final(&md->md5, hash); psSha1Final(&md->sha1, hash + MD5_HASHLEN); }
void psHmacSha384Update(psHmacSha384_t *ctx, const unsigned char *buf, uint32_t len) { #ifdef CRYPTO_ASSERT psAssert(ctx != NULL && buf != NULL); #endif psSha384Update(&ctx->sha384, buf, len); }
void psHmacMd5Update(psHmacMd5_t *ctx, const unsigned char *buf, uint32_t len) { #ifdef CRYPTO_ASSERT psAssert(ctx != NULL && buf != NULL); #endif psMd5Update(&ctx->md5, buf, len); }
void psSha256Update(psDigestContext_t *md, const unsigned char *buf, uint32 len) { uint32 n; psAssert(md != NULL); psAssert(buf != NULL); while (len > 0) { if (md->sha256.curlen == 0 && len >= 64) { sha256_compress(md, (unsigned char *)buf); #ifdef HAVE_NATIVE_INT64 md->sha256.length += 512; #else n = (md->sha256.lengthLo + 512) & 0xFFFFFFFFL; if (n < md->sha256.lengthLo) { md->sha256.lengthHi++; } md->sha256.lengthLo = n; #endif /* HAVE_NATIVE_INT64 */ buf += 64; len -= 64; } else { n = min(len, (64 - md->sha256.curlen)); memcpy(md->sha256.buf + md->sha256.curlen, buf, (size_t)n); md->sha256.curlen += n; buf += n; len -= n; if (md->sha256.curlen == 64) { sha256_compress (md, md->sha256.buf); #ifdef HAVE_NATIVE_INT64 md->sha256.length += 512; #else n = (md->sha256.lengthLo + 512) & 0xFFFFFFFFL; if (n < md->sha256.lengthLo) { md->sha256.lengthHi++; } md->sha256.lengthLo = n; #endif /* HAVE_NATIVE_INT64 */ md->sha256.curlen = 0; } } } return; }