u_char * mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) { static u_char m[EVP_MAX_MD_SIZE]; u_char b[4], nonce[8]; if (mac->mac_len > sizeof(m)) fatal("mac_compute: mac too long %u %lu", mac->mac_len, (u_long)sizeof(m)); switch (mac->type) { case SSH_EVP: put_u32(b, seqno); /* reset HMAC context */ HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); HMAC_Update(&mac->evp_ctx, b, sizeof(b)); HMAC_Update(&mac->evp_ctx, data, datalen); HMAC_Final(&mac->evp_ctx, m, NULL); break; case SSH_UMAC: put_u64(nonce, seqno); umac_update(mac->umac_ctx, data, datalen); umac_final(mac->umac_ctx, m, nonce); break; default: fatal("mac_compute: unknown MAC type"); } return (m); }
int mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen, u_char *digest, size_t dlen) { static u_char m[MAC_DIGEST_LEN_MAX]; u_char b[4], nonce[8]; if (mac->mac_len > sizeof(m)) return SSH_ERR_INTERNAL_ERROR; switch (mac->type) { case SSH_EVP: POKE_U32(b, seqno); /* reset HMAC context */ if (HMAC_Init(&mac->evp_ctx, NULL, 0, NULL) != 1 || HMAC_Update(&mac->evp_ctx, b, sizeof(b)) != 1 || HMAC_Update(&mac->evp_ctx, data, datalen) != 1 || HMAC_Final(&mac->evp_ctx, m, NULL) != 1) return SSH_ERR_LIBCRYPTO_ERROR; break; case SSH_UMAC: POKE_U64(nonce, seqno); umac_update(mac->umac_ctx, data, datalen); umac_final(mac->umac_ctx, m, nonce); break; default: return SSH_ERR_INVALID_ARGUMENT; } if (digest != NULL) { if (dlen > mac->mac_len) dlen = mac->mac_len; memcpy(digest, m, dlen); } return 0; }
u_char * mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) { static union { u_char m[EVP_MAX_MD_SIZE]; u_int64_t for_align; } u; u_char b[4]; #ifdef UMAC_HAS_BEEN_UNBROKEN u_char nonce[8]; #endif if (mac->mac_len > sizeof(u)) fatal("mac_compute: mac too long %u %lu", mac->mac_len, (u_long)sizeof(u)); switch (mac->type) { case SSH_EVP: put_u32(b, seqno); /* reset HMAC context */ HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); HMAC_Update(&mac->evp_ctx, b, sizeof(b)); HMAC_Update(&mac->evp_ctx, data, datalen); HMAC_Final(&mac->evp_ctx, u.m, NULL); break; #ifdef UMAC_HAS_BEEN_UNBROKEN case SSH_UMAC: put_u64(nonce, seqno); umac_update(mac->umac_ctx, data, datalen); umac_final(mac->umac_ctx, u.m, nonce); break; case SSH_UMAC128: put_u64(nonce, seqno); umac128_update(mac->umac_ctx, data, datalen); umac128_final(mac->umac_ctx, u.m, nonce); break; #endif default: fatal("mac_compute: unknown MAC type"); } return (u.m); }
u_char * mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) { static union { u_char m[EVP_MAX_MD_SIZE]; u_int64_t for_align; } u; u_char b[4]; u_char nonce[8]; if (mac->mac_len > sizeof(u)) fatal("mac_compute: mac too long %u %zu", mac->mac_len, sizeof(u)); switch (mac->type) { case SSH_DIGEST: put_u32(b, seqno); /* reset HMAC context */ if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 || ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 || ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 || ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0) fatal("ssh_hmac failed"); break; case SSH_UMAC: put_u64(nonce, seqno); umac_update(mac->umac_ctx, data, datalen); umac_final(mac->umac_ctx, u.m, nonce); break; case SSH_UMAC128: put_u64(nonce, seqno); umac128_update(mac->umac_ctx, data, datalen); umac128_final(mac->umac_ctx, u.m, nonce); break; default: fatal("mac_compute: unknown MAC type"); } return (u.m); }