diff options
Diffstat (limited to 'mac.c')
-rw-r--r-- | mac.c | 52 |
1 files changed, 41 insertions, 11 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mac.c,v 1.18 2012/06/28 05:07:45 dtucker Exp $ */ | 1 | /* $OpenBSD: mac.c,v 1.21 2012/12/11 22:51:45 sthen Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -48,6 +48,7 @@ | |||
48 | 48 | ||
49 | #define SSH_EVP 1 /* OpenSSL EVP-based MAC */ | 49 | #define SSH_EVP 1 /* OpenSSL EVP-based MAC */ |
50 | #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ | 50 | #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ |
51 | #define SSH_UMAC128 3 | ||
51 | 52 | ||
52 | struct { | 53 | struct { |
53 | char *name; | 54 | char *name; |
@@ -56,19 +57,36 @@ struct { | |||
56 | int truncatebits; /* truncate digest if != 0 */ | 57 | int truncatebits; /* truncate digest if != 0 */ |
57 | int key_len; /* just for UMAC */ | 58 | int key_len; /* just for UMAC */ |
58 | int len; /* just for UMAC */ | 59 | int len; /* just for UMAC */ |
60 | int etm; /* Encrypt-then-MAC */ | ||
59 | } macs[] = { | 61 | } macs[] = { |
60 | { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 }, | 62 | /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
61 | { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 }, | 63 | { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, |
64 | { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 }, | ||
62 | #ifdef HAVE_EVP_SHA256 | 65 | #ifdef HAVE_EVP_SHA256 |
63 | { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, -1, -1 }, | 66 | { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 }, |
64 | { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, -1, -1 }, | 67 | { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 }, |
65 | #endif | 68 | #endif |
66 | { "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 }, | 69 | { "hmac-md5", SSH_EVP, EVP_md5, 0, 0, 0, 0 }, |
67 | { "hmac-md5-96", SSH_EVP, EVP_md5, 96, -1, -1 }, | 70 | { "hmac-md5-96", SSH_EVP, EVP_md5, 96, 0, 0, 0 }, |
68 | { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, -1, -1 }, | 71 | { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, |
69 | { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, -1, -1 }, | 72 | { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, |
70 | { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64 }, | 73 | { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 }, |
71 | { NULL, 0, NULL, 0, -1, -1 } | 74 | { "umac-128@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 0 }, |
75 | |||
76 | /* Encrypt-then-MAC variants */ | ||
77 | { "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 }, | ||
78 | { "hmac-sha1-96-etm@openssh.com", SSH_EVP, EVP_sha1, 96, 0, 0, 1 }, | ||
79 | #ifdef HAVE_EVP_SHA256 | ||
80 | { "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 }, | ||
81 | { "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 }, | ||
82 | #endif | ||
83 | { "hmac-md5-etm@openssh.com", SSH_EVP, EVP_md5, 0, 0, 0, 1 }, | ||
84 | { "hmac-md5-96-etm@openssh.com", SSH_EVP, EVP_md5, 96, 0, 0, 1 }, | ||
85 | { "hmac-ripemd160-etm@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 1 }, | ||
86 | { "umac-64-etm@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 1 }, | ||
87 | { "umac-128-etm@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 1 }, | ||
88 | |||
89 | { NULL, 0, NULL, 0, 0, 0, 0 } | ||
72 | }; | 90 | }; |
73 | 91 | ||
74 | static void | 92 | static void |
@@ -88,6 +106,7 @@ mac_setup_by_id(Mac *mac, int which) | |||
88 | } | 106 | } |
89 | if (macs[which].truncatebits != 0) | 107 | if (macs[which].truncatebits != 0) |
90 | mac->mac_len = macs[which].truncatebits / 8; | 108 | mac->mac_len = macs[which].truncatebits / 8; |
109 | mac->etm = macs[which].etm; | ||
91 | } | 110 | } |
92 | 111 | ||
93 | int | 112 | int |
@@ -122,6 +141,9 @@ mac_init(Mac *mac) | |||
122 | case SSH_UMAC: | 141 | case SSH_UMAC: |
123 | mac->umac_ctx = umac_new(mac->key); | 142 | mac->umac_ctx = umac_new(mac->key); |
124 | return 0; | 143 | return 0; |
144 | case SSH_UMAC128: | ||
145 | mac->umac_ctx = umac128_new(mac->key); | ||
146 | return 0; | ||
125 | default: | 147 | default: |
126 | return -1; | 148 | return -1; |
127 | } | 149 | } |
@@ -151,6 +173,11 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) | |||
151 | umac_update(mac->umac_ctx, data, datalen); | 173 | umac_update(mac->umac_ctx, data, datalen); |
152 | umac_final(mac->umac_ctx, m, nonce); | 174 | umac_final(mac->umac_ctx, m, nonce); |
153 | break; | 175 | break; |
176 | case SSH_UMAC128: | ||
177 | put_u64(nonce, seqno); | ||
178 | umac128_update(mac->umac_ctx, data, datalen); | ||
179 | umac128_final(mac->umac_ctx, m, nonce); | ||
180 | break; | ||
154 | default: | 181 | default: |
155 | fatal("mac_compute: unknown MAC type"); | 182 | fatal("mac_compute: unknown MAC type"); |
156 | } | 183 | } |
@@ -163,6 +190,9 @@ mac_clear(Mac *mac) | |||
163 | if (mac->type == SSH_UMAC) { | 190 | if (mac->type == SSH_UMAC) { |
164 | if (mac->umac_ctx != NULL) | 191 | if (mac->umac_ctx != NULL) |
165 | umac_delete(mac->umac_ctx); | 192 | umac_delete(mac->umac_ctx); |
193 | } else if (mac->type == SSH_UMAC128) { | ||
194 | if (mac->umac_ctx != NULL) | ||
195 | umac128_delete(mac->umac_ctx); | ||
166 | } else if (mac->evp_md != NULL) | 196 | } else if (mac->evp_md != NULL) |
167 | HMAC_cleanup(&mac->evp_ctx); | 197 | HMAC_cleanup(&mac->evp_ctx); |
168 | mac->evp_md = NULL; | 198 | mac->evp_md = NULL; |