00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/md5.h"
00019 #include "crypto/sha1.h"
00020 #include "tlsv1_common.h"
00021 #include "tlsv1_record.h"
00022
00023
00035 int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl,
00036 u16 cipher_suite)
00037 {
00038 const struct tls_cipher_suite *suite;
00039 const struct tls_cipher_data *data;
00040
00041 wpa_printf(MSG_DEBUG, "TLSv1: Selected cipher suite: 0x%04x",
00042 cipher_suite);
00043 rl->cipher_suite = cipher_suite;
00044
00045 suite = tls_get_cipher_suite(cipher_suite);
00046 if (suite == NULL)
00047 return -1;
00048
00049 if (suite->hash == TLS_HASH_MD5) {
00050 rl->hash_alg = CRYPTO_HASH_ALG_HMAC_MD5;
00051 rl->hash_size = MD5_MAC_LEN;
00052 } else if (suite->hash == TLS_HASH_SHA) {
00053 rl->hash_alg = CRYPTO_HASH_ALG_HMAC_SHA1;
00054 rl->hash_size = SHA1_MAC_LEN;
00055 }
00056
00057 data = tls_get_cipher_data(suite->cipher);
00058 if (data == NULL)
00059 return -1;
00060
00061 rl->key_material_len = data->key_material;
00062 rl->iv_size = data->block_size;
00063 rl->cipher_alg = data->alg;
00064
00065 return 0;
00066 }
00067
00068
00077 int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl)
00078 {
00079 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New write cipher suite "
00080 "0x%04x", rl->cipher_suite);
00081 rl->write_cipher_suite = rl->cipher_suite;
00082 os_memset(rl->write_seq_num, 0, TLS_SEQ_NUM_LEN);
00083
00084 if (rl->write_cbc) {
00085 crypto_cipher_deinit(rl->write_cbc);
00086 rl->write_cbc = NULL;
00087 }
00088 if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
00089 rl->write_cbc = crypto_cipher_init(rl->cipher_alg,
00090 rl->write_iv, rl->write_key,
00091 rl->key_material_len);
00092 if (rl->write_cbc == NULL) {
00093 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
00094 "cipher");
00095 return -1;
00096 }
00097 }
00098
00099 return 0;
00100 }
00101
00102
00111 int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
00112 {
00113 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New read cipher suite "
00114 "0x%04x", rl->cipher_suite);
00115 rl->read_cipher_suite = rl->cipher_suite;
00116 os_memset(rl->read_seq_num, 0, TLS_SEQ_NUM_LEN);
00117
00118 if (rl->read_cbc) {
00119 crypto_cipher_deinit(rl->read_cbc);
00120 rl->read_cbc = NULL;
00121 }
00122 if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
00123 rl->read_cbc = crypto_cipher_init(rl->cipher_alg,
00124 rl->read_iv, rl->read_key,
00125 rl->key_material_len);
00126 if (rl->read_cbc == NULL) {
00127 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
00128 "cipher");
00129 return -1;
00130 }
00131 }
00132
00133 return 0;
00134 }
00135
00136
00152 int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
00153 size_t buf_size, size_t payload_len, size_t *out_len)
00154 {
00155 u8 *pos, *ct_start, *length, *payload;
00156 struct crypto_hash *hmac;
00157 size_t clen;
00158
00159 pos = buf;
00160
00161 ct_start = pos;
00162 *pos++ = content_type;
00163
00164 WPA_PUT_BE16(pos, TLS_VERSION);
00165 pos += 2;
00166
00167 length = pos;
00168 WPA_PUT_BE16(length, payload_len);
00169 pos += 2;
00170
00171
00172 payload = pos;
00173 pos += payload_len;
00174
00175 if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
00176 hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
00177 rl->hash_size);
00178 if (hmac == NULL) {
00179 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
00180 "to initialize HMAC");
00181 return -1;
00182 }
00183 crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
00184
00185 crypto_hash_update(hmac, ct_start, pos - ct_start);
00186 clen = buf + buf_size - pos;
00187 if (clen < rl->hash_size) {
00188 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
00189 "enough room for MAC");
00190 crypto_hash_finish(hmac, NULL, NULL);
00191 return -1;
00192 }
00193
00194 if (crypto_hash_finish(hmac, pos, &clen) < 0) {
00195 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
00196 "to calculate HMAC");
00197 return -1;
00198 }
00199 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Write HMAC",
00200 pos, clen);
00201 pos += clen;
00202 if (rl->iv_size) {
00203 size_t len = pos - payload;
00204 size_t pad;
00205 pad = (len + 1) % rl->iv_size;
00206 if (pad)
00207 pad = rl->iv_size - pad;
00208 if (pos + pad + 1 > buf + buf_size) {
00209 wpa_printf(MSG_DEBUG, "TLSv1: No room for "
00210 "block cipher padding");
00211 return -1;
00212 }
00213 os_memset(pos, pad, pad + 1);
00214 pos += pad + 1;
00215 }
00216
00217 if (crypto_cipher_encrypt(rl->write_cbc, payload,
00218 payload, pos - payload) < 0)
00219 return -1;
00220 }
00221
00222 WPA_PUT_BE16(length, pos - length - 2);
00223 inc_byte_array(rl->write_seq_num, TLS_SEQ_NUM_LEN);
00224
00225 *out_len = pos - buf;
00226
00227 return 0;
00228 }
00229
00230
00245 int tlsv1_record_receive(struct tlsv1_record_layer *rl,
00246 const u8 *in_data, size_t in_len,
00247 u8 *out_data, size_t *out_len, u8 *alert)
00248 {
00249 size_t i, rlen, hlen;
00250 u8 padlen;
00251 struct crypto_hash *hmac;
00252 u8 len[2], hash[100];
00253
00254 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
00255 in_data, in_len);
00256
00257 if (in_len < TLS_RECORD_HEADER_LEN) {
00258 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu)",
00259 (unsigned long) in_len);
00260 *alert = TLS_ALERT_DECODE_ERROR;
00261 return -1;
00262 }
00263
00264 wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d "
00265 "length %d", in_data[0], in_data[1], in_data[2],
00266 WPA_GET_BE16(in_data + 3));
00267
00268 if (in_data[0] != TLS_CONTENT_TYPE_HANDSHAKE &&
00269 in_data[0] != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC &&
00270 in_data[0] != TLS_CONTENT_TYPE_ALERT &&
00271 in_data[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
00272 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type 0x%x",
00273 in_data[0]);
00274 *alert = TLS_ALERT_UNEXPECTED_MESSAGE;
00275 return -1;
00276 }
00277
00278 if (WPA_GET_BE16(in_data + 1) != TLS_VERSION) {
00279 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version "
00280 "%d.%d", in_data[1], in_data[2]);
00281 *alert = TLS_ALERT_PROTOCOL_VERSION;
00282 return -1;
00283 }
00284
00285 rlen = WPA_GET_BE16(in_data + 3);
00286
00287
00288 if (TLS_RECORD_HEADER_LEN + rlen > 18432) {
00289 wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
00290 (unsigned long) (TLS_RECORD_HEADER_LEN + rlen));
00291 *alert = TLS_ALERT_RECORD_OVERFLOW;
00292 return -1;
00293 }
00294
00295 in_data += TLS_RECORD_HEADER_LEN;
00296 in_len -= TLS_RECORD_HEADER_LEN;
00297
00298 if (rlen > in_len) {
00299 wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included "
00300 "(rlen=%lu > in_len=%lu)",
00301 (unsigned long) rlen, (unsigned long) in_len);
00302 *alert = TLS_ALERT_DECODE_ERROR;
00303 return -1;
00304 }
00305
00306 in_len = rlen;
00307
00308 if (*out_len < in_len) {
00309 wpa_printf(MSG_DEBUG, "TLSv1: Not enough output buffer for "
00310 "processing received record");
00311 *alert = TLS_ALERT_INTERNAL_ERROR;
00312 return -1;
00313 }
00314
00315 os_memcpy(out_data, in_data, in_len);
00316 *out_len = in_len;
00317
00318 if (rl->read_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
00319 if (crypto_cipher_decrypt(rl->read_cbc, out_data,
00320 out_data, in_len) < 0) {
00321 *alert = TLS_ALERT_DECRYPTION_FAILED;
00322 return -1;
00323 }
00324 if (rl->iv_size) {
00325 if (in_len == 0) {
00326 wpa_printf(MSG_DEBUG, "TLSv1: Too short record"
00327 " (no pad)");
00328 *alert = TLS_ALERT_DECODE_ERROR;
00329 return -1;
00330 }
00331 padlen = out_data[in_len - 1];
00332 if (padlen >= in_len) {
00333 wpa_printf(MSG_DEBUG, "TLSv1: Incorrect pad "
00334 "length (%u, in_len=%lu) in "
00335 "received record",
00336 padlen, (unsigned long) in_len);
00337 *alert = TLS_ALERT_DECRYPTION_FAILED;
00338 return -1;
00339 }
00340 for (i = in_len - padlen; i < in_len; i++) {
00341 if (out_data[i] != padlen) {
00342 wpa_hexdump(MSG_DEBUG,
00343 "TLSv1: Invalid pad in "
00344 "received record",
00345 out_data + in_len - padlen,
00346 padlen);
00347 *alert = TLS_ALERT_DECRYPTION_FAILED;
00348 return -1;
00349 }
00350 }
00351
00352 *out_len -= padlen + 1;
00353 }
00354
00355 wpa_hexdump(MSG_MSGDUMP,
00356 "TLSv1: Record Layer - Decrypted data",
00357 out_data, in_len);
00358
00359 if (*out_len < rl->hash_size) {
00360 wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no "
00361 "hash value");
00362 *alert = TLS_ALERT_INTERNAL_ERROR;
00363 return -1;
00364 }
00365
00366 *out_len -= rl->hash_size;
00367
00368 hmac = crypto_hash_init(rl->hash_alg, rl->read_mac_secret,
00369 rl->hash_size);
00370 if (hmac == NULL) {
00371 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
00372 "to initialize HMAC");
00373 *alert = TLS_ALERT_INTERNAL_ERROR;
00374 return -1;
00375 }
00376
00377 crypto_hash_update(hmac, rl->read_seq_num, TLS_SEQ_NUM_LEN);
00378
00379 crypto_hash_update(hmac, in_data - TLS_RECORD_HEADER_LEN, 3);
00380 WPA_PUT_BE16(len, *out_len);
00381 crypto_hash_update(hmac, len, 2);
00382 crypto_hash_update(hmac, out_data, *out_len);
00383 hlen = sizeof(hash);
00384 if (crypto_hash_finish(hmac, hash, &hlen) < 0) {
00385 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
00386 "to calculate HMAC");
00387 return -1;
00388 }
00389 if (hlen != rl->hash_size ||
00390 os_memcmp(hash, out_data + *out_len, hlen) != 0) {
00391 wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in "
00392 "received message");
00393 *alert = TLS_ALERT_BAD_RECORD_MAC;
00394 return -1;
00395 }
00396 }
00397
00398
00399 if (TLS_RECORD_HEADER_LEN + *out_len > 17408) {
00400 wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
00401 (unsigned long) (TLS_RECORD_HEADER_LEN + *out_len));
00402 *alert = TLS_ALERT_RECORD_OVERFLOW;
00403 return -1;
00404 }
00405
00406 inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN);
00407
00408 return 0;
00409 }