void dtls_mac(dtls_hmac_context_t *hmac_ctx, const unsigned char *record, const unsigned char *packet, size_t length, unsigned char *buf) { uint16 L; dtls_int_to_uint16(L, length); assert(hmac_ctx); dtls_hmac_update(hmac_ctx, record +3, sizeof(uint16) + sizeof(uint48)); dtls_hmac_update(hmac_ctx, record, sizeof(uint8) + sizeof(uint16)); dtls_hmac_update(hmac_ctx, L, sizeof(uint16)); dtls_hmac_update(hmac_ctx, packet, length); dtls_hmac_finalize(hmac_ctx, buf); }
size_t dtls_pre_master_secret(unsigned char *key, size_t keylen, unsigned char *result) { unsigned char *p = result; dtls_int_to_uint16(p, keylen); p += sizeof(uint16); memset(p, 0, keylen); p += keylen; memcpy(p, result, sizeof(uint16)); p += sizeof(uint16); memcpy(p, key, keylen); return (sizeof(uint16) + keylen) << 1; }
/** * Creates the CBC-MAC for the additional authentication data that * is sent in cleartext. * * \param ctx The crypto context for the AES encryption. * \param msg The message starting with the additional authentication data. * \param la The number of additional authentication bytes in \p msg. * \param B The input buffer for crypto operations. When this function * is called, \p B must be initialized with \c B0 (the first * authentication block. * \param X The output buffer where the result of the CBC calculation * is placed. * \return The result is written to \p X. */ void add_auth_data(rijndael_ctx *ctx, const unsigned char *msg, size_t la, unsigned char B[DTLS_CCM_BLOCKSIZE], unsigned char X[DTLS_CCM_BLOCKSIZE]) { size_t i,j; rijndael_encrypt(ctx, B, X); memset(B, 0, DTLS_CCM_BLOCKSIZE); if (!la) return; #ifndef WITH_CONTIKI if (la < 0xFF00) { /* 2^16 - 2^8 */ j = 2; dtls_int_to_uint16(B, la); } else if (la <= UINT32_MAX) { j = 6; dtls_int_to_uint16(B, 0xFFFE); dtls_int_to_uint32(B+2, la); } else { j = 10; dtls_int_to_uint16(B, 0xFFFF); dtls_ulong_to_uint64(B+2, la); } #else /* WITH_CONTIKI */ /* With Contiki, we are building for small devices and thus * anticipate that the number of additional authentication bytes * will not exceed 65280 bytes (0xFF00) and we can skip the * workarounds required for j=6 and j=10 on devices with a word size * of 32 bits or 64 bits, respectively. */ assert(la < 0xFF00); j = 2; dtls_int_to_uint16(B, la); #endif /* WITH_CONTIKI */ i = min(DTLS_CCM_BLOCKSIZE - j, la); memcpy(B + j, msg, i); la -= i; msg += i; memxor(B, X, DTLS_CCM_BLOCKSIZE); rijndael_encrypt(ctx, B, X); while (la > DTLS_CCM_BLOCKSIZE) { for (i = 0; i < DTLS_CCM_BLOCKSIZE; ++i) B[i] = X[i] ^ *msg++; la -= DTLS_CCM_BLOCKSIZE; rijndael_encrypt(ctx, B, X); } if (la) { memset(B, 0, DTLS_CCM_BLOCKSIZE); memcpy(B, msg, la); memxor(B, X, DTLS_CCM_BLOCKSIZE); rijndael_encrypt(ctx, B, X); } }