From 62aaf07478aa9883073133223878075bb411058b Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Mon, 30 Jan 2017 08:21:12 +0000 Subject: [PATCH] Add support for mbed TLS and deprecate polarssl support --- common.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++- player.c | 17 ++++++ rtsp.c | 33 ++++++++++++ shairport.c | 14 +++++ 4 files changed, 210 insertions(+), 1 deletion(-) diff --git a/common.c b/common.c index 3389e5f9..d2eb17e4 100644 --- a/common.c +++ b/common.c @@ -67,6 +67,17 @@ #endif #endif +#ifdef HAVE_LIBMBEDTLS +#include +#include +#include +#include +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" + +#endif + + #include // true if Shairport Sync is supposed to be sending output to the output device, false otherwise @@ -125,6 +136,59 @@ void inform(char *format, ...) { daemon_log(LOG_INFO, "%s", s); } +#ifdef HAVE_LIBMBEDTLS +char *base64_enc(uint8_t *input, int length) { + char *buf = NULL; + size_t dlen = 0; + int rc = mbedtls_base64_encode(NULL, 0, &dlen, input, length); + if (rc && (rc != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)) + debug(1, "Error %d getting length of base64 encode.", rc); + else { + buf = (char *)malloc(dlen); + rc = mbedtls_base64_encode((unsigned char *)buf, dlen, &dlen, input, length); + if (rc != 0) + debug(1, "Error %d encoding base64.", rc); + } + return buf; +} + +uint8_t *base64_dec(char *input, int *outlen) { + // slight problem here is that Apple cut the padding off their challenges. We must restore it + // before passing it in to the decoder, it seems + uint8_t *buf = NULL; + size_t dlen = 0; + int inbufsize = ((strlen(input) + 3) / 4) * 4; // this is the size of the input buffer we will + // send to the decoder, but we need space for 3 + // extra "="s and a NULL + char *inbuf = malloc(inbufsize + 4); + if (inbuf == 0) + debug(1, "Can't malloc memory for inbuf in base64_decode."); + else { + strcpy(inbuf, input); + strcat(inbuf, "==="); + // debug(1,"base64_dec called with string \"%s\", length %d, filled string: \"%s\", length %d.", + // input,strlen(input),inbuf,inbufsize); + int rc = mbedtls_base64_decode(NULL, 0, &dlen, (unsigned char *)inbuf, inbufsize); + if (rc && (rc != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)) + debug(1, "Error %d getting decode length, result is %d.", rc, dlen); + else { + // debug(1,"Decode size is %d.",dlen); + buf = malloc(dlen); + if (buf == 0) + debug(1, "Can't allocate memory in base64_dec."); + else { + rc = mbedtls_base64_decode(buf, dlen, &dlen, (unsigned char *)inbuf, inbufsize); + if (rc != 0) + debug(1, "Error %d in base64_dec.", rc); + } + } + free(inbuf); + } + *outlen = dlen; + return buf; +} +#endif + #ifdef HAVE_LIBPOLARSSL char *base64_enc(uint8_t *input, int length) { char *buf = NULL; @@ -279,6 +343,62 @@ uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) { } #endif +#ifdef HAVE_LIBMBEDTLS +uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) { + mbedtls_pk_context pkctx; + mbedtls_rsa_context *trsa; + const char *pers = "rsa_encrypt"; + size_t olen = *outlen; + int rc; + + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + + mbedtls_entropy_init(&entropy); + + mbedtls_ctr_drbg_init(&ctr_drbg); + mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, + (const unsigned char *)pers, strlen(pers)); + + mbedtls_pk_init(&pkctx); + + rc = mbedtls_pk_parse_key(&pkctx, (unsigned char *)super_secret_key, sizeof(super_secret_key), NULL, 0); + if (rc != 0) + debug(1, "Error %d reading the private key.", rc); + + uint8_t *outbuf = NULL; + trsa = mbedtls_pk_rsa(pkctx); + + switch (mode) { + case RSA_MODE_AUTH: + mbedtls_rsa_set_padding(trsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE); + outbuf = malloc(trsa->len); + rc = mbedtls_rsa_pkcs1_encrypt(trsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PRIVATE, + inlen, input, outbuf); + if (rc != 0) + debug(1, "mbedtls_pk_encrypt error %d.", rc); + *outlen = trsa->len; + break; + case RSA_MODE_KEY: + mbedtls_rsa_set_padding(trsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1); + outbuf = malloc(trsa->len); + rc = mbedtls_rsa_pkcs1_decrypt(trsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PRIVATE, + &olen, input, outbuf, trsa->len); + if (rc != 0) + debug(1, "mbedtls_pk_decrypt error %d.", rc); + *outlen = olen; + break; + default: + die("bad rsa mode"); + } + + mbedtls_ctr_drbg_free(&ctr_drbg); + mbedtls_entropy_free(&entropy); + mbedtls_pk_free(&pkctx); + return outbuf; +} +#endif + #ifdef HAVE_LIBPOLARSSL uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) { rsa_context trsa; @@ -583,7 +703,7 @@ char *str_replace(const char *string, const char *substr, const char *replacemen /* from http://burtleburtle.net/bob/rand/smallprng.html */ -typedef uint64_t u8; +// typedef uint64_t u8; typedef struct ranctx { uint64_t a; uint64_t b; @@ -616,3 +736,28 @@ void r64init(uint64_t seed) { raninit(&rx, seed); } uint64_t r64u() { return (ranval(&rx)); } int64_t r64i() { return (ranval(&rx) >> 1); } + +/* generate an array of 64-bit random numbers */ +const int ranarraylength = 1009; // these will be 8-byte numbers. + +uint64_t *ranarray; + +int ranarraynext; + +void ranarrayinit() { + ranarray = (uint64_t*)malloc(ranarraylength*sizeof(uint64_t)); + int i; + for (i=0;i> 1); } + diff --git a/player.c b/player.c index c09ec67c..edc3dfbf 100644 --- a/player.c +++ b/player.c @@ -47,6 +47,11 @@ #include "config.h" +#ifdef HAVE_LIBMBEDTLS +#include +#include +#endif + #ifdef HAVE_LIBPOLARSSL #include #include @@ -92,6 +97,10 @@ static int max_frame_size_change; // maximal resampling shift - conservative //#define OUTFRAME_BYTES(max_frames_per_packet) (4 * (max_frames_per_packet + 3)) +#ifdef HAVE_LIBMBEDTLS +static mbedtls_aes_context dctx; +#endif + #ifdef HAVE_LIBPOLARSSL static aes_context dctx; #endif @@ -315,6 +324,9 @@ static int alac_decode(short *dest, int *destlen, uint8_t *buf, int len) { unsigned char iv[16]; int aeslen = len & ~0xf; memcpy(iv, aesiv, sizeof(iv)); +#ifdef HAVE_LIBMBEDTLS + mbedtls_aes_crypt_cbc(&dctx, MBEDTLS_AES_DECRYPT, aeslen, iv, buf, packet); +#endif #ifdef HAVE_LIBPOLARSSL aes_crypt_cbc(&dctx, AES_DECRYPT, aeslen, iv, buf, packet); #endif @@ -2389,6 +2401,11 @@ int player_play(stream_cfg *stream, pthread_t *player_thread) { die("specified buffer starting fill %d > buffer size %d", config.buffer_start_fill, BUFFER_FRAMES); if (encrypted) { +#ifdef HAVE_LIBMBEDTLS + memset(&dctx, 0, sizeof(mbedtls_aes_context)); + mbedtls_aes_setkey_dec(&dctx, stream->aeskey, 128); +#endif + #ifdef HAVE_LIBPOLARSSL memset(&dctx, 0, sizeof(aes_context)); aes_setkey_dec(&dctx, stream->aeskey, 128); diff --git a/rtsp.c b/rtsp.c index 9464a22b..e58c10b4 100644 --- a/rtsp.c +++ b/rtsp.c @@ -50,6 +50,10 @@ #include #endif +#ifdef HAVE_LIBMBEDTLS +#include +#endif + #ifdef HAVE_LIBPOLARSSL #include #endif @@ -1614,6 +1618,23 @@ static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) { MD5_Final(digest_mu, &ctx); #endif +#ifdef HAVE_LIBMBEDTLS + mbedtls_md5_context tctx; + mbedtls_md5_starts(&tctx); + mbedtls_md5_update(&tctx, (const unsigned char *)username, strlen(username)); + mbedtls_md5_update(&tctx, (unsigned char *)":", 1); + mbedtls_md5_update(&tctx, (const unsigned char *)realm, strlen(realm)); + mbedtls_md5_update(&tctx, (unsigned char *)":", 1); + mbedtls_md5_update(&tctx, (const unsigned char *)config.password, + strlen(config.password)); + mbedtls_md5_finish(&tctx, digest_urp); + mbedtls_md5_starts(&tctx); + mbedtls_md5_update(&tctx, (const unsigned char *)req->method, strlen(req->method)); + mbedtls_md5_update(&tctx, (unsigned char *)":", 1); + mbedtls_md5_update(&tctx, (const unsigned char *)uri, strlen(uri)); + mbedtls_md5_finish(&tctx, digest_mu); +#endif + #ifdef HAVE_LIBPOLARSSL md5_context tctx; md5_starts(&tctx); @@ -1647,6 +1668,18 @@ static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) { MD5_Final(digest_total, &ctx); #endif +#ifdef HAVE_LIBMBEDTLS + mbedtls_md5_starts(&tctx); + mbedtls_md5_update(&tctx, buf, 32); + mbedtls_md5_update(&tctx, (unsigned char *)":", 1); + mbedtls_md5_update(&tctx, (const unsigned char *)*nonce, strlen(*nonce)); + mbedtls_md5_update(&tctx, (unsigned char *)":", 1); + for (i = 0; i < 16; i++) + sprintf((char *)buf + 2 * i, "%02x", digest_mu[i]); + mbedtls_md5_update(&tctx, buf, 32); + mbedtls_md5_finish(&tctx, digest_total); +#endif + #ifdef HAVE_LIBPOLARSSL md5_starts(&tctx); md5_update(&tctx, buf, 32); diff --git a/shairport.c b/shairport.c index 6d37f96c..9b3065a6 100644 --- a/shairport.c +++ b/shairport.c @@ -42,6 +42,10 @@ #include "config.h" +#ifdef HAVE_LIBMBEDTLS +#include +#endif + #ifdef HAVE_LIBPOLARSSL #include #endif @@ -109,6 +113,9 @@ char *get_version_string() { char *version_string = malloc(200); if (version_string) { strcpy(version_string, PACKAGE_VERSION); +#ifdef HAVE_LIBMBEDTLS + strcat(version_string, "-mbedTLS"); +#endif #ifdef HAVE_LIBPOLARSSL strcat(version_string, "-PolarSSL"); #endif @@ -1133,6 +1140,13 @@ int main(int argc, char **argv) { MD5_Final(ap_md5, &ctx); #endif +#ifdef HAVE_LIBMBEDTLS + mbedtls_md5_context tctx; + mbedtls_md5_starts(&tctx); + mbedtls_md5_update(&tctx, (unsigned char *)config.service_name, strlen(config.service_name)); + mbedtls_md5_finish(&tctx, ap_md5); +#endif + #ifdef HAVE_LIBPOLARSSL md5_context tctx; md5_starts(&tctx);