/** * checks a message authenticity * * The function computes CMAC of the given plain text and compares * it against cmac4. Returns 1 if CMACs matches. * * @param skey 128-bit session key * @param cmac4: points to CMAC message part, i.e. 4 bytes CMAC * @param plain: plain text to be CMACked and checked against * @param len: length of plain text in bytes */ int macan_check_cmac(struct macan_ctx *ctx, struct macan_key *skey, const uint8_t *cmac4, uint8_t *plain, uint8_t *fill_time, unsigned len) { uint8_t cmac[16]; uint64_t time; int32_t *ftime = (int32_t *)fill_time; int i; if (!fill_time) { macan_aes_cmac(skey, len, cmac, plain); /* add memcmp instead of memchk */ return memchk(cmac4, cmac, 4); } time = macan_get_time(ctx); for (i = -1; i <= 1; i++) { *ftime = htole32((int)time + i); macan_aes_cmac(skey, len, cmac, plain); if (memcmp(cmac4, cmac, 4) == 0) { return 1; } } return 0; }
/** * checks a message authenticity * * The function computes CMAC of the given plain text and compares * it against cmac4. Returns 1 if CMACs matches. * * @param skey 128-bit session key * @param cmac4: points to CMAC message part, i.e. 4 bytes CMAC * @param plain: plain text to be CMACked and checked against * @param len: length of plain text in bytes */ int macan_check_cmac(struct macan_ctx *ctx, struct macan_key *skey, const uint8_t *cmac4, uint8_t *plain, int time_index, unsigned len) { uint8_t cmac[16]; uint32_t *time_ptr; if (time_index < 0 || (unsigned)time_index > len - sizeof(*time_ptr)) { macan_aes_cmac(skey, len, cmac, plain); /* add memcmp instead of memchk */ return memchk(cmac4, cmac, 4); } uint32_t time = (uint32_t)macan_get_time(ctx); int delta_t; time_ptr = (uint32_t *)&plain[time_index]; for (delta_t = -1; delta_t <= 1; delta_t++) { *time_ptr = htole32(time + (uint32_t)delta_t); macan_aes_cmac(skey, len, cmac, plain); if (memcmp(cmac4, cmac, 4) == 0) { return 1; } } return 0; }
/** * sign() - signs a message with CMAC * @skey: 128-bit session key * @cmac4: 4 bytes of the CMAC signature will be written to * @plain: a plain text to sign * @len: length of the plain text */ void macan_sign(struct macan_key *skey, uint8_t *cmac4, uint8_t *plain, unsigned len) { uint8_t cmac[16]; macan_aes_cmac(skey, len, cmac, plain); memcpy(cmac4, cmac, 4); }