MT#55283 rework crypto debug code

Switch from thread-local allocated string object to a stack allocated
one. Use auto cleanup to manage storage duration and final logging.

Fixes intermittent random failures of the leak checker.

Change-Id: Ie6afb27e6fd1accbe641fc62175d553a0558de0d
pull/1855/merge
Richard Fuchs 2 weeks ago
parent 9f9aaa5332
commit 56f171b64e

@ -18,8 +18,6 @@
#include "xt_RTPENGINE.h"
__thread GString *crypto_debug_string;
static int aes_cm_encrypt_rtp(struct crypto_context *, struct rtp_header *, str *, uint32_t);
static int aes_cm_encrypt_rtcp(struct crypto_context *, struct rtcp_packet *, str *, uint32_t);
static int aes_gcm_encrypt_rtp(struct crypto_context *, struct rtp_header *, str *, uint32_t);
@ -1012,9 +1010,9 @@ void crypto_init_main(void) {
}
}
void __crypto_debug_printf(const char *fmt, ...) {
void __crypto_debug_printf(crypto_debug_string *gs, const char *fmt, ...) {
va_list va;
va_start(va, fmt);
g_string_append_vprintf(crypto_debug_string, fmt, va);
g_string_append_vprintf(gs, fmt, va);
va_end(va);
}

@ -854,18 +854,18 @@ int rtcp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
return -1;
i = atomic_get_na(&ssrc_ctx->stats->rtcp_seq);
crypto_debug_init(1);
crypto_debug_printf("RTCP SSRC %" PRIx32 ", idx %u, plain pl: ",
g_autoptr(crypto_debug_string) cds = crypto_debug_init(true);
crypto_debug_printf(cds, "RTCP SSRC %" PRIx32 ", idx %u, plain pl: ",
rtcp->ssrc, i);
crypto_debug_dump(&payload);
crypto_debug_dump(cds, &payload);
int prev_len = payload.len;
if (!c->params.session_params.unencrypted_srtcp && crypto_encrypt_rtcp(c, rtcp, &payload, i))
return -1;
s->len += payload.len - prev_len;
crypto_debug_printf(", enc pl: ");
crypto_debug_dump(&payload);
crypto_debug_printf(cds, ", enc pl: ");
crypto_debug_dump(cds, &payload);
idx = (void *) s->s + s->len;
*idx = htonl((c->params.session_params.unencrypted_srtcp ? 0ULL : 0x80000000ULL) | i);
@ -874,17 +874,15 @@ int rtcp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
to_auth = *s;
rtp_append_mki(s, c);
rtp_append_mki(s, c, cds);
if (c->params.crypto_suite->srtcp_auth_tag) {
c->params.crypto_suite->hash_rtcp(c, s->s + s->len, &to_auth);
crypto_debug_printf(", auth: ");
crypto_debug_dump_raw(s->s + s->len, c->params.crypto_suite->srtcp_auth_tag);
crypto_debug_printf(cds, ", auth: ");
crypto_debug_dump_raw(cds, s->s + s->len, c->params.crypto_suite->srtcp_auth_tag);
s->len += c->params.crypto_suite->srtcp_auth_tag;
}
crypto_debug_finish();
return 1;
}
@ -904,16 +902,16 @@ int rtcp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
if (check_session_keys(c))
return -1;
crypto_debug_init(1);
g_autoptr(crypto_debug_string) cds = crypto_debug_init(true);
if (srtp_payloads(&to_auth, &to_decrypt, &auth_tag, NULL,
c->params.crypto_suite->srtcp_auth_tag, c->params.mki_len,
s, &payload))
return -1;
crypto_debug_printf("RTCP SSRC %" PRIx32 ", enc pl: ",
crypto_debug_printf(cds, "RTCP SSRC %" PRIx32 ", enc pl: ",
rtcp->ssrc);
crypto_debug_dump(&to_decrypt);
crypto_debug_dump(cds, &to_decrypt);
err = "short packet";
if (to_decrypt.len < sizeof(idx))
@ -922,7 +920,7 @@ int rtcp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
memcpy(&idx, to_decrypt.s + to_decrypt.len, sizeof(idx));
idx = ntohl(idx);
crypto_debug_printf(", idx %" PRIu32, idx);
crypto_debug_printf(cds, ", idx %" PRIu32, idx);
if (!auth_tag.len)
goto decrypt;
@ -931,10 +929,10 @@ int rtcp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
assert(sizeof(hmac) >= auth_tag.len);
c->params.crypto_suite->hash_rtcp(c, hmac, &to_auth);
crypto_debug_printf(", rcv hmac: ");
crypto_debug_dump(&auth_tag);
crypto_debug_printf(", calc hmac: ");
crypto_debug_dump_raw(hmac, auth_tag.len);
crypto_debug_printf(cds, ", rcv hmac: ");
crypto_debug_dump(cds, &auth_tag);
crypto_debug_printf(cds, ", calc hmac: ");
crypto_debug_dump_raw(cds, hmac, auth_tag.len);
err = "authentication failed";
if (str_memcmp(&auth_tag, hmac))
@ -946,16 +944,14 @@ decrypt:;
if (crypto_decrypt_rtcp(c, rtcp, &to_decrypt, idx & 0x7fffffffULL))
return -1;
crypto_debug_printf(", dec pl: ");
crypto_debug_dump(&to_decrypt);
crypto_debug_printf(cds, ", dec pl: ");
crypto_debug_dump(cds, &to_decrypt);
}
*s = to_auth;
s->len -= sizeof(idx);
s->len -= prev_len - to_decrypt.len;
crypto_debug_finish();
return 0;
error:

@ -43,13 +43,13 @@ error:
return -1;
}
static unsigned int packet_index(struct ssrc_ctx *ssrc_ctx, struct rtp_header *rtp) {
static unsigned int packet_index(struct ssrc_ctx *ssrc_ctx, struct rtp_header *rtp, crypto_debug_string **cds) {
uint16_t seq;
seq = ntohs(rtp->seq_num);
crypto_debug_init((seq & 0x1ff) == (ssrc_ctx->parent->h.ssrc & 0x1ff));
crypto_debug_printf("SSRC %" PRIx32 ", seq %" PRIu16, ssrc_ctx->parent->h.ssrc, seq);
*cds = crypto_debug_init((seq & 0x1ff) == (ssrc_ctx->parent->h.ssrc & 0x1ff));
crypto_debug_printf(*cds, "SSRC %" PRIx32 ", seq %" PRIu16, ssrc_ctx->parent->h.ssrc, seq);
/* rfc 3711 section 3.3.1 */
unsigned int srtp_index = atomic_get_na(&ssrc_ctx->stats->ext_seq);
@ -61,7 +61,7 @@ static unsigned int packet_index(struct ssrc_ctx *ssrc_ctx, struct rtp_header *r
uint32_t roc = (srtp_index & 0xffffffff0000ULL) >> 16;
uint32_t v = 0;
crypto_debug_printf(", prev seq %u, s_l %" PRIu16 ", ROC %" PRIu32,
crypto_debug_printf(*cds, ", prev seq %u, s_l %" PRIu16 ", ROC %" PRIu32,
srtp_index, s_l, roc);
if (s_l < 0x8000) {
@ -79,12 +79,12 @@ static unsigned int packet_index(struct ssrc_ctx *ssrc_ctx, struct rtp_header *r
srtp_index = (uint64_t)(((v << 16) | seq) & 0xffffffffffffULL);
atomic_set_na(&ssrc_ctx->stats->ext_seq, srtp_index);
crypto_debug_printf(", v %" PRIu32 ", ext seq %u", v, srtp_index);
crypto_debug_printf(*cds, ", v %" PRIu32 ", ext seq %u", v, srtp_index);
return srtp_index;
}
void rtp_append_mki(str *s, struct crypto_context *c) {
void rtp_append_mki(str *s, struct crypto_context *c, crypto_debug_string *cds) {
char *p;
if (!c->params.mki_len)
@ -95,8 +95,8 @@ void rtp_append_mki(str *s, struct crypto_context *c) {
memcpy(p, c->params.mki, c->params.mki_len);
s->len += c->params.mki_len;
crypto_debug_printf(", MKI: ");
crypto_debug_dump_raw(p, c->params.mki_len);
crypto_debug_printf(cds, ", MKI: ");
crypto_debug_dump_raw(cds, p, c->params.mki_len);
}
/* rfc 3711, section 3.3 */
@ -112,10 +112,11 @@ int rtp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
if (check_session_keys(c))
return -1;
index = packet_index(ssrc_ctx, rtp);
g_autoptr(crypto_debug_string) cds = NULL;
index = packet_index(ssrc_ctx, rtp, &cds);
crypto_debug_printf(", plain pl: ");
crypto_debug_dump(&payload);
crypto_debug_printf(cds, ", plain pl: ");
crypto_debug_dump(cds, &payload);
/* rfc 3711 section 3.1 */
int prev_len = payload.len;
@ -123,22 +124,20 @@ int rtp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
return -1;
s->len += payload.len - prev_len;
crypto_debug_printf(", enc pl: ");
crypto_debug_dump(&payload);
crypto_debug_printf(cds, ", enc pl: ");
crypto_debug_dump(cds, &payload);
to_auth = *s;
rtp_append_mki(s, c);
rtp_append_mki(s, c, cds);
if (!c->params.session_params.unauthenticated_srtp && c->params.crypto_suite->srtp_auth_tag) {
c->params.crypto_suite->hash_rtp(c, s->s + s->len, &to_auth, index);
crypto_debug_printf(", auth: ");
crypto_debug_dump_raw(s->s + s->len, c->params.crypto_suite->srtp_auth_tag);
crypto_debug_printf(cds, ", auth: ");
crypto_debug_dump_raw(cds, s->s + s->len, c->params.crypto_suite->srtp_auth_tag);
s->len += c->params.crypto_suite->srtp_auth_tag;
}
crypto_debug_finish();
return 0;
}
@ -150,7 +149,8 @@ int rtp_update_index(str *s, struct packet_stream *ps, struct ssrc_ctx *ssrc) {
return -1;
if (rtp_payload(&rtp, NULL, s))
return -1;
packet_index(ssrc, rtp);
g_autoptr(crypto_debug_string) cds = NULL;
packet_index(ssrc, rtp, &cds);
return 0;
}
@ -168,15 +168,16 @@ int rtp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
if (check_session_keys(c))
return -1;
index = packet_index(ssrc_ctx, rtp);
g_autoptr(crypto_debug_string) cds = NULL;
index = packet_index(ssrc_ctx, rtp, &cds);
if (srtp_payloads(&to_auth, &to_decrypt, &auth_tag, NULL,
c->params.session_params.unauthenticated_srtp ? 0 : c->params.crypto_suite->srtp_auth_tag,
c->params.mki_len,
s, &payload))
return -1;
crypto_debug_printf(", enc pl: ");
crypto_debug_dump(&to_decrypt);
crypto_debug_printf(cds, ", enc pl: ");
crypto_debug_dump(cds, &to_decrypt);
if (!auth_tag.len)
goto decrypt;
@ -185,10 +186,10 @@ int rtp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
assert(sizeof(hmac) >= auth_tag.len);
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
crypto_debug_printf(", rcv hmac: ");
crypto_debug_dump(&auth_tag);
crypto_debug_printf(", calc hmac: ");
crypto_debug_dump_raw(hmac, auth_tag.len);
crypto_debug_printf(cds, ", rcv hmac: ");
crypto_debug_dump(cds, &auth_tag);
crypto_debug_printf(cds, ", calc hmac: ");
crypto_debug_dump_raw(cds, hmac, auth_tag.len);
if (!str_memcmp(&auth_tag, hmac))
goto decrypt;
@ -197,8 +198,8 @@ int rtp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
index += 0x10000;
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
crypto_debug_printf(", calc hmac 2: ");
crypto_debug_dump_raw(hmac, auth_tag.len);
crypto_debug_printf(cds, ", calc hmac 2: ");
crypto_debug_dump_raw(cds, hmac, auth_tag.len);
if (!str_memcmp(&auth_tag, hmac))
goto decrypt_idx;
@ -207,8 +208,8 @@ int rtp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
index -= 0x20000;
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
crypto_debug_printf(", calc hmac 3: ");
crypto_debug_dump_raw(hmac, auth_tag.len);
crypto_debug_printf(cds, ", calc hmac 3: ");
crypto_debug_dump_raw(cds, hmac, auth_tag.len);
if (!str_memcmp(&auth_tag, hmac))
goto decrypt_idx;
@ -217,8 +218,8 @@ int rtp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
index &= 0xffff;
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
crypto_debug_printf(", calc hmac 4: ");
crypto_debug_dump_raw(hmac, auth_tag.len);
crypto_debug_printf(cds, ", calc hmac 4: ");
crypto_debug_dump_raw(cds, hmac, auth_tag.len);
if (!str_memcmp(&auth_tag, hmac))
goto decrypt_idx;
@ -267,14 +268,12 @@ decrypt:;
}
}
crypto_debug_printf(", dec pl: ");
crypto_debug_dump(&to_decrypt);
crypto_debug_printf(cds, ", dec pl: ");
crypto_debug_dump(cds, &to_decrypt);
*s = to_auth;
s->len -= prev_len - to_decrypt.len;
crypto_debug_finish();
return 0;
error:

@ -100,9 +100,6 @@ struct crypto_context {
extern const struct crypto_suite *crypto_suites;
extern const unsigned int num_crypto_suites;
extern __thread GString *crypto_debug_string;
void crypto_init_main(void);
@ -260,35 +257,35 @@ INLINE int crypto_params_sdes_check_limitations(str_case_ht sdes_only,
#include <inttypes.h>
INLINE void crypto_debug_init(int flag) {
typedef GString crypto_debug_string;
INLINE crypto_debug_string *crypto_debug_init(bool flag) {
if (rtpe_config.common.log_levels[log_level_index_srtp] < LOG_DEBUG)
return;
if (crypto_debug_string)
g_string_free(crypto_debug_string, TRUE);
crypto_debug_string = NULL;
return NULL;
if (!flag)
return;
crypto_debug_string = g_string_new("");
return NULL;
return g_string_new("");
}
void __crypto_debug_printf(const char *fmt, ...) __attribute__((format(printf,1,2)));
#define crypto_debug_printf(f, ...) \
if (crypto_debug_string) \
__crypto_debug_printf(f, ##__VA_ARGS__)
INLINE void crypto_debug_dump_raw(const char *b, int len) {
void __crypto_debug_printf(crypto_debug_string *gs, const char *fmt, ...) __attribute__((format(printf,2,3)));
#define crypto_debug_printf(gs, f, ...) \
do { \
if (gs) \
__crypto_debug_printf(gs, f, ##__VA_ARGS__); \
} while (0)
INLINE void crypto_debug_dump_raw(crypto_debug_string *gs, const char *b, int len) {
for (int i = 0; i < len; i++)
crypto_debug_printf("%02" PRIx8, (unsigned char) b[i]);
crypto_debug_printf(gs, "%02" PRIx8, (unsigned char) b[i]);
}
INLINE void crypto_debug_dump(const str *s) {
crypto_debug_dump_raw(s->s, s->len);
INLINE void crypto_debug_dump(crypto_debug_string *gs, const str *s) {
crypto_debug_dump_raw(gs, s->s, s->len);
}
INLINE void crypto_debug_finish(void) {
if (!crypto_debug_string)
return;
ilogs(srtp, LOG_NOTICE, "Crypto debug: %.*s", (int) crypto_debug_string->len, crypto_debug_string->str);
g_string_free(crypto_debug_string, TRUE);
crypto_debug_string = NULL;
INLINE void crypto_debug_finish(crypto_debug_string *gs) {
ilogs(srtp, LOG_NOTICE, "Crypto debug: %.*s", (int) gs->len, gs->str);
g_string_free(gs, TRUE);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(crypto_debug_string, crypto_debug_finish);
#endif

@ -13,6 +13,8 @@ enum ssrc_dir;
struct ssrc_ctx;
struct codec_store;
typedef GString crypto_debug_string;
const rtp_payload_type *get_rtp_payload_type(unsigned int, struct codec_store *);
int rtp_avp2savp(str *, struct crypto_context *, struct ssrc_ctx *);
@ -20,7 +22,7 @@ int rtp_savp2avp(str *, struct crypto_context *, struct ssrc_ctx *);
int rtp_update_index(str *, struct packet_stream *, struct ssrc_ctx *);
void rtp_append_mki(str *s, struct crypto_context *c);
void rtp_append_mki(str *s, struct crypto_context *c, crypto_debug_string *);
int srtp_payloads(str *to_auth, str *to_decrypt, str *auth_tag, str *mki,
int auth_len, int mki_len,
const str *packet, const str *payload);

Loading…
Cancel
Save