mirror of
https://github.com/openssh/libopenssh
synced 2026-04-17 02:06:45 +00:00
defatal mac.[ch]
Conflicts: ssh/packet.c
This commit is contained in:
16
ssh/kex.h
16
ssh/kex.h
@@ -27,9 +27,10 @@
|
||||
#define KEX_H
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
#include "mac.h"
|
||||
|
||||
#define KEX_COOKIE_LEN 16
|
||||
|
||||
#define KEX_DH1 "diffie-hellman-group1-sha1"
|
||||
@@ -76,7 +77,7 @@ enum kex_exchange {
|
||||
#define KEX_INIT_SENT 0x0001
|
||||
|
||||
typedef struct Kex Kex;
|
||||
typedef struct Mac Mac;
|
||||
typedef struct sshmac Mac;
|
||||
typedef struct Comp Comp;
|
||||
typedef struct Enc Enc;
|
||||
typedef struct Newkeys Newkeys;
|
||||
@@ -90,17 +91,6 @@ struct Enc {
|
||||
u_char *key;
|
||||
u_char *iv;
|
||||
};
|
||||
struct Mac {
|
||||
char *name;
|
||||
int enabled;
|
||||
u_int mac_len;
|
||||
u_char *key;
|
||||
u_int key_len;
|
||||
int type;
|
||||
const EVP_MD *evp_md;
|
||||
HMAC_CTX evp_ctx;
|
||||
struct umac_ctx *umac_ctx;
|
||||
};
|
||||
struct Comp {
|
||||
int type;
|
||||
int enabled;
|
||||
|
||||
78
ssh/mac.c
78
ssh/mac.c
@@ -38,6 +38,7 @@
|
||||
#include "kex.h"
|
||||
#include "mac.h"
|
||||
#include "misc.h"
|
||||
#include "err.h"
|
||||
|
||||
#include "umac.h"
|
||||
|
||||
@@ -66,7 +67,7 @@ struct {
|
||||
{ NULL, 0, NULL, 0, -1, -1 }
|
||||
};
|
||||
|
||||
static void
|
||||
static int
|
||||
mac_setup_by_id(Mac *mac, int which)
|
||||
{
|
||||
int evp_len;
|
||||
@@ -74,7 +75,7 @@ mac_setup_by_id(Mac *mac, int which)
|
||||
if (mac->type == SSH_EVP) {
|
||||
mac->evp_md = (*macs[which].mdfunc)();
|
||||
if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0)
|
||||
fatal("mac %s len %d", mac->name, evp_len);
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
mac->key_len = mac->mac_len = (u_int)evp_len;
|
||||
} else {
|
||||
mac->mac_len = macs[which].len / 8;
|
||||
@@ -83,6 +84,7 @@ mac_setup_by_id(Mac *mac, int which)
|
||||
}
|
||||
if (macs[which].truncatebits != 0)
|
||||
mac->mac_len = macs[which].truncatebits / 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -93,63 +95,72 @@ mac_setup(Mac *mac, char *name)
|
||||
for (i = 0; macs[i].name; i++) {
|
||||
if (strcmp(name, macs[i].name) == 0) {
|
||||
if (mac != NULL)
|
||||
mac_setup_by_id(mac, i);
|
||||
debug2("mac_setup: found %s", name);
|
||||
return (0);
|
||||
return mac_setup_by_id(mac, i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
debug2("mac_setup: unknown %s", name);
|
||||
return (-1);
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
int
|
||||
mac_init(Mac *mac)
|
||||
{
|
||||
if (mac->key == NULL)
|
||||
fatal("mac_init: no key");
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
switch (mac->type) {
|
||||
case SSH_EVP:
|
||||
if (mac->evp_md == NULL)
|
||||
return -1;
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
HMAC_CTX_init(&mac->evp_ctx);
|
||||
HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md);
|
||||
if (HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len,
|
||||
mac->evp_md) != 1) {
|
||||
HMAC_CTX_cleanup(&mac->evp_ctx);
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
}
|
||||
return 0;
|
||||
case SSH_UMAC:
|
||||
mac->umac_ctx = umac_new(mac->key);
|
||||
if ((mac->umac_ctx = umac_new(mac->key)) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
u_char *
|
||||
mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
|
||||
int
|
||||
mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen,
|
||||
u_char *digest, size_t dlen)
|
||||
{
|
||||
static u_char m[EVP_MAX_MD_SIZE];
|
||||
static u_char m[MAC_DIGEST_LEN_MAX];
|
||||
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));
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
switch (mac->type) {
|
||||
case SSH_EVP:
|
||||
put_u32(b, seqno);
|
||||
POKE_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);
|
||||
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:
|
||||
put_u64(nonce, seqno);
|
||||
POKE_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 SSH_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
return (m);
|
||||
if (digest != NULL) {
|
||||
if (dlen > mac->mac_len)
|
||||
dlen = mac->mac_len;
|
||||
memcpy(digest, m, dlen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -172,19 +183,16 @@ mac_valid(const char *names)
|
||||
char *maclist, *cp, *p;
|
||||
|
||||
if (names == NULL || strcmp(names, "") == 0)
|
||||
return (0);
|
||||
maclist = cp = xstrdup(names);
|
||||
return 0;
|
||||
if ((maclist = cp = xstrdup(names)) == NULL)
|
||||
return 0;
|
||||
for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0';
|
||||
(p = strsep(&cp, MAC_SEP))) {
|
||||
if (mac_setup(NULL, p) < 0) {
|
||||
debug("bad mac %s [%s]", p, names);
|
||||
xfree(maclist);
|
||||
return (0);
|
||||
} else {
|
||||
debug3("mac ok: %s [%s]", p, names);
|
||||
free(maclist);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
debug3("macs ok: [%s]", names);
|
||||
xfree(maclist);
|
||||
return (1);
|
||||
free(maclist);
|
||||
return 1;
|
||||
}
|
||||
|
||||
32
ssh/mac.h
32
ssh/mac.h
@@ -23,8 +23,32 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SSHMAC_H
|
||||
#define SSHMAC_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#define MAC_DIGEST_LEN_MAX EVP_MAX_MD_SIZE
|
||||
|
||||
struct sshmac {
|
||||
char *name;
|
||||
int enabled;
|
||||
u_int mac_len;
|
||||
u_char *key;
|
||||
u_int key_len;
|
||||
int type;
|
||||
const EVP_MD *evp_md;
|
||||
HMAC_CTX evp_ctx;
|
||||
struct umac_ctx *umac_ctx;
|
||||
};
|
||||
|
||||
int mac_valid(const char *);
|
||||
int mac_setup(Mac *, char *);
|
||||
int mac_init(Mac *);
|
||||
u_char *mac_compute(Mac *, u_int32_t, u_char *, int);
|
||||
void mac_clear(Mac *);
|
||||
int mac_setup(struct sshmac *, char *);
|
||||
int mac_init(struct sshmac *);
|
||||
int mac_compute(struct sshmac *, u_int32_t, u_char *, int,
|
||||
u_char *, size_t);
|
||||
void mac_clear(struct sshmac *);
|
||||
|
||||
#endif /* SSHMAC_H */
|
||||
|
||||
27
ssh/packet.c
27
ssh/packet.c
@@ -298,8 +298,8 @@ ssh_packet_stop_discard(struct ssh *ssh)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
(void) mac_compute(state->packet_discard_mac,
|
||||
state->p_read.seqnr,
|
||||
sshbuf_ptr(state->incoming_packet),
|
||||
PACKET_MAX_SIZE);
|
||||
sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE,
|
||||
NULL, 0);
|
||||
}
|
||||
logit("Finished discarding for %.200s", get_remote_ipaddr());
|
||||
cleanup_exit(255);
|
||||
@@ -856,8 +856,9 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
|
||||
enc = &state->newkeys[mode]->enc;
|
||||
mac = &state->newkeys[mode]->mac;
|
||||
comp = &state->newkeys[mode]->comp;
|
||||
if (mac_init(mac) == 0)
|
||||
mac->enabled = 1;
|
||||
if ((r = mac_init(mac)) != 0)
|
||||
fatal("newkeys: mac_init_failed: %s", ssh_err(r));
|
||||
mac->enabled = 1;
|
||||
DBG(debug("cipher_init_context: %d", mode));
|
||||
if ((r = cipher_init(cc, enc->cipher, enc->key, enc->key_len,
|
||||
enc->iv, enc->block_size, crypt_type)) != 0)
|
||||
@@ -934,7 +935,7 @@ int
|
||||
ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
u_char type, *cp, *macbuf = NULL;
|
||||
u_char type, *cp, macbuf[MAC_DIGEST_LEN_MAX];
|
||||
u_char padlen, pad;
|
||||
u_int packet_length = 0;
|
||||
u_int i, len;
|
||||
@@ -1021,9 +1022,11 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
|
||||
/* compute MAC over seqnr and packet(length fields, payload, padding) */
|
||||
if (mac && mac->enabled) {
|
||||
macbuf = mac_compute(mac, state->p_send.seqnr,
|
||||
if ((r = mac_compute(mac, state->p_send.seqnr,
|
||||
sshbuf_ptr(state->outgoing_packet),
|
||||
sshbuf_len(state->outgoing_packet));
|
||||
sshbuf_len(state->outgoing_packet),
|
||||
macbuf, sizeof(macbuf))) != 0)
|
||||
goto out;
|
||||
DBG(debug("done calc MAC out #%d", state->p_send.seqnr));
|
||||
}
|
||||
/* encrypt packet and append to output buffer. */
|
||||
@@ -1374,7 +1377,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
u_int padlen, need;
|
||||
u_char *macbuf, *cp;
|
||||
u_char macbuf[MAC_DIGEST_LEN_MAX], *cp;
|
||||
u_int maclen, block_size;
|
||||
Enc *enc = NULL;
|
||||
Mac *mac = NULL;
|
||||
@@ -1457,10 +1460,12 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
* increment sequence number for incoming packet
|
||||
*/
|
||||
if (mac && mac->enabled) {
|
||||
macbuf = mac_compute(mac, state->p_read.seqnr,
|
||||
if ((r = mac_compute(mac, state->p_read.seqnr,
|
||||
sshbuf_ptr(state->incoming_packet),
|
||||
sshbuf_len(state->incoming_packet));
|
||||
if (timingsafe_bcmp(macbuf, sshbuf_ptr(state->input),
|
||||
sshbuf_len(state->incoming_packet),
|
||||
macbuf, sizeof(macbuf))) != 0)
|
||||
goto out;
|
||||
if (timingsafe_bcmp(macbuf, buffer_ptr(state->input),
|
||||
mac->mac_len) != 0) {
|
||||
logit("Corrupted MAC on input.");
|
||||
if (need > PACKET_MAX_SIZE)
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "umac.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -1197,7 +1196,7 @@ int umac_delete(struct umac_ctx *ctx)
|
||||
if (ctx) {
|
||||
if (ALLOC_BOUNDARY)
|
||||
ctx = (struct umac_ctx *)ctx->free_ptr;
|
||||
xfree(ctx);
|
||||
free(ctx);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
@@ -1213,7 +1212,7 @@ struct umac_ctx *umac_new(u_char key[])
|
||||
size_t bytes_to_add;
|
||||
aes_int_key prf_key;
|
||||
|
||||
octx = ctx = xmalloc(sizeof(*ctx) + ALLOC_BOUNDARY);
|
||||
octx = ctx = malloc(sizeof(*ctx) + ALLOC_BOUNDARY);
|
||||
if (ctx) {
|
||||
if (ALLOC_BOUNDARY) {
|
||||
bytes_to_add = ALLOC_BOUNDARY -
|
||||
|
||||
Reference in New Issue
Block a user