static unsigned char * ccm_encrypt(br_sslrec_ccm_context *cc, int record_type, unsigned version, void *data, size_t *data_len) { br_ccm_context zc; unsigned char *buf; unsigned char nonce[12], header[13]; size_t len; buf = (unsigned char *)data; len = *data_len; /* * Make nonce; the explicit part is an encoding of the sequence * number. */ memcpy(nonce, cc->iv, sizeof cc->iv); br_enc64be(nonce + 4, cc->seq); /* * Assemble synthetic header for the AAD. */ br_enc64be(header, cc->seq ++); header[8] = (unsigned char)record_type; br_enc16be(header + 9, version); br_enc16be(header + 11, len); /* * Perform CCM encryption. */ br_ccm_init(&zc, &cc->bc.vtable); br_ccm_reset(&zc, nonce, sizeof nonce, sizeof header, len, cc->tag_len); br_ccm_aad_inject(&zc, header, sizeof header); br_ccm_flip(&zc); br_ccm_run(&zc, 1, buf, len); br_ccm_get_tag(&zc, buf + len); /* * Assemble header and adjust pointer/length. */ len += 8 + cc->tag_len; buf -= 13; memcpy(buf + 5, nonce + 4, 8); buf[0] = (unsigned char)record_type; br_enc16be(buf + 1, version); br_enc16be(buf + 3, len); *data_len = len + 5; return buf; }
static unsigned char * ccm_decrypt(br_sslrec_ccm_context *cc, int record_type, unsigned version, void *data, size_t *data_len) { br_ccm_context zc; unsigned char *buf; unsigned char nonce[12], header[13]; size_t len; buf = (unsigned char *)data + 8; len = *data_len - (8 + cc->tag_len); /* * Make nonce (implicit + explicit parts). */ memcpy(nonce, cc->iv, sizeof cc->iv); memcpy(nonce + 4, data, 8); /* * Assemble synthetic header for the AAD. */ br_enc64be(header, cc->seq ++); header[8] = (unsigned char)record_type; br_enc16be(header + 9, version); br_enc16be(header + 11, len); /* * Perform CCM decryption. */ br_ccm_init(&zc, &cc->bc.vtable); br_ccm_reset(&zc, nonce, sizeof nonce, sizeof header, len, cc->tag_len); br_ccm_aad_inject(&zc, header, sizeof header); br_ccm_flip(&zc); br_ccm_run(&zc, 0, buf, len); if (!br_ccm_check_tag(&zc, buf + len)) { return NULL; } *data_len = len; return buf; }
static void sha2small_out(const br_sha224_context *cc, void *dst, int num) { unsigned char buf[64]; uint32_t val[8]; size_t ptr; ptr = (size_t)cc->count & 63; memcpy(buf, cc->buf, ptr); memcpy(val, cc->val, sizeof val); buf[ptr ++] = 0x80; if (ptr > 56) { memset(buf + ptr, 0, 64 - ptr); br_sha2small_round(buf, val); memset(buf, 0, 56); } else { memset(buf + ptr, 0, 56 - ptr); } br_enc64be(buf + 56, cc->count << 3); br_sha2small_round(buf, val); br_range_enc32be(dst, val, num); }
static void sha2big_out(const br_sha384_context *cc, void *dst, int num) { unsigned char buf[128]; uint64_t val[8]; size_t ptr; ptr = (size_t)cc->count & 127; memcpy(buf, cc->buf, ptr); memcpy(val, cc->val, sizeof val); buf[ptr ++] = 0x80; if (ptr > 112) { memset(buf + ptr, 0, 128 - ptr); sha2big_round(buf, val); memset(buf, 0, 112); } else { memset(buf + ptr, 0, 112 - ptr); } br_enc64be(buf + 112, cc->count >> 61); br_enc64be(buf + 120, cc->count << 3); sha2big_round(buf, val); br_range_enc64be(dst, val, num); }