tlsv1_record.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /*
  2. * TLSv1 Record Protocol
  3. * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #include "common.h"
  16. #include "crypto/md5.h"
  17. #include "crypto/sha1.h"
  18. #include "tlsv1_common.h"
  19. #include "tlsv1_record.h"
  20. /**
  21. * tlsv1_record_set_cipher_suite - TLS record layer: Set cipher suite
  22. * @rl: Pointer to TLS record layer data
  23. * @cipher_suite: New cipher suite
  24. * Returns: 0 on success, -1 on failure
  25. *
  26. * This function is used to prepare TLS record layer for cipher suite change.
  27. * tlsv1_record_change_write_cipher() and
  28. * tlsv1_record_change_read_cipher() functions can then be used to change the
  29. * currently used ciphers.
  30. */
  31. int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl,
  32. u16 cipher_suite)
  33. {
  34. const struct tls_cipher_suite *suite;
  35. const struct tls_cipher_data *data;
  36. wpa_printf(MSG_DEBUG, "TLSv1: Selected cipher suite: 0x%04x",
  37. cipher_suite);
  38. rl->cipher_suite = cipher_suite;
  39. suite = tls_get_cipher_suite(cipher_suite);
  40. if (suite == NULL)
  41. return -1;
  42. if (suite->hash == TLS_HASH_MD5) {
  43. rl->hash_alg = CRYPTO_HASH_ALG_HMAC_MD5;
  44. rl->hash_size = MD5_MAC_LEN;
  45. } else if (suite->hash == TLS_HASH_SHA) {
  46. rl->hash_alg = CRYPTO_HASH_ALG_HMAC_SHA1;
  47. rl->hash_size = SHA1_MAC_LEN;
  48. }
  49. data = tls_get_cipher_data(suite->cipher);
  50. if (data == NULL)
  51. return -1;
  52. rl->key_material_len = data->key_material;
  53. rl->iv_size = data->block_size;
  54. rl->cipher_alg = data->alg;
  55. return 0;
  56. }
  57. /**
  58. * tlsv1_record_change_write_cipher - TLS record layer: Change write cipher
  59. * @rl: Pointer to TLS record layer data
  60. * Returns: 0 on success (cipher changed), -1 on failure
  61. *
  62. * This function changes TLS record layer to use the new cipher suite
  63. * configured with tlsv1_record_set_cipher_suite() for writing.
  64. */
  65. int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl)
  66. {
  67. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New write cipher suite "
  68. "0x%04x", rl->cipher_suite);
  69. rl->write_cipher_suite = rl->cipher_suite;
  70. os_memset(rl->write_seq_num, 0, TLS_SEQ_NUM_LEN);
  71. if (rl->write_cbc) {
  72. crypto_cipher_deinit(rl->write_cbc);
  73. rl->write_cbc = NULL;
  74. }
  75. if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
  76. rl->write_cbc = crypto_cipher_init(rl->cipher_alg,
  77. rl->write_iv, rl->write_key,
  78. rl->key_material_len);
  79. if (rl->write_cbc == NULL) {
  80. wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
  81. "cipher");
  82. return -1;
  83. }
  84. }
  85. return 0;
  86. }
  87. /**
  88. * tlsv1_record_change_read_cipher - TLS record layer: Change read cipher
  89. * @rl: Pointer to TLS record layer data
  90. * Returns: 0 on success (cipher changed), -1 on failure
  91. *
  92. * This function changes TLS record layer to use the new cipher suite
  93. * configured with tlsv1_record_set_cipher_suite() for reading.
  94. */
  95. int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
  96. {
  97. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New read cipher suite "
  98. "0x%04x", rl->cipher_suite);
  99. rl->read_cipher_suite = rl->cipher_suite;
  100. os_memset(rl->read_seq_num, 0, TLS_SEQ_NUM_LEN);
  101. if (rl->read_cbc) {
  102. crypto_cipher_deinit(rl->read_cbc);
  103. rl->read_cbc = NULL;
  104. }
  105. if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
  106. rl->read_cbc = crypto_cipher_init(rl->cipher_alg,
  107. rl->read_iv, rl->read_key,
  108. rl->key_material_len);
  109. if (rl->read_cbc == NULL) {
  110. wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
  111. "cipher");
  112. return -1;
  113. }
  114. }
  115. return 0;
  116. }
  117. /**
  118. * tlsv1_record_send - TLS record layer: Send a message
  119. * @rl: Pointer to TLS record layer data
  120. * @content_type: Content type (TLS_CONTENT_TYPE_*)
  121. * @buf: Buffer for the generated TLS message (needs to have extra space for
  122. * header and HMAC)
  123. * @buf_size: Maximum buf size
  124. * @payload: Payload to be sent
  125. * @payload_len: Length of the payload
  126. * @out_len: Buffer for returning the used buf length
  127. * Returns: 0 on success, -1 on failure
  128. *
  129. * This function fills in the TLS record layer header, adds HMAC, and encrypts
  130. * the data using the current write cipher.
  131. */
  132. int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
  133. size_t buf_size, const u8 *payload, size_t payload_len,
  134. size_t *out_len)
  135. {
  136. u8 *pos, *ct_start, *length, *cpayload;
  137. struct crypto_hash *hmac;
  138. size_t clen;
  139. pos = buf;
  140. if (pos + TLS_RECORD_HEADER_LEN > buf + buf_size)
  141. return -1;
  142. /* ContentType type */
  143. ct_start = pos;
  144. *pos++ = content_type;
  145. /* ProtocolVersion version */
  146. WPA_PUT_BE16(pos, TLS_VERSION);
  147. pos += 2;
  148. /* uint16 length */
  149. length = pos;
  150. WPA_PUT_BE16(length, payload_len);
  151. pos += 2;
  152. cpayload = pos;
  153. /*
  154. * opaque fragment[TLSPlaintext.length]
  155. * (opaque content[TLSCompressed.length] in GenericBlockCipher)
  156. */
  157. if (pos + payload_len > buf + buf_size)
  158. return -1;
  159. os_memmove(pos, payload, payload_len);
  160. pos += payload_len;
  161. if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
  162. /*
  163. * MAC calculated over seq_num + TLSCompressed.type +
  164. * TLSCompressed.version + TLSCompressed.length +
  165. * TLSCompressed.fragment
  166. */
  167. hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
  168. rl->hash_size);
  169. if (hmac == NULL) {
  170. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  171. "to initialize HMAC");
  172. return -1;
  173. }
  174. crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
  175. /* type + version + length + fragment */
  176. crypto_hash_update(hmac, ct_start, TLS_RECORD_HEADER_LEN);
  177. crypto_hash_update(hmac, payload, payload_len);
  178. clen = buf + buf_size - pos;
  179. if (clen < rl->hash_size) {
  180. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
  181. "enough room for MAC");
  182. crypto_hash_finish(hmac, NULL, NULL);
  183. return -1;
  184. }
  185. if (crypto_hash_finish(hmac, pos, &clen) < 0) {
  186. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  187. "to calculate HMAC");
  188. return -1;
  189. }
  190. wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Write HMAC",
  191. pos, clen);
  192. pos += clen;
  193. if (rl->iv_size) {
  194. size_t len = pos - cpayload;
  195. size_t pad;
  196. pad = (len + 1) % rl->iv_size;
  197. if (pad)
  198. pad = rl->iv_size - pad;
  199. if (pos + pad + 1 > buf + buf_size) {
  200. wpa_printf(MSG_DEBUG, "TLSv1: No room for "
  201. "block cipher padding");
  202. return -1;
  203. }
  204. os_memset(pos, pad, pad + 1);
  205. pos += pad + 1;
  206. }
  207. if (crypto_cipher_encrypt(rl->write_cbc, cpayload,
  208. cpayload, pos - cpayload) < 0)
  209. return -1;
  210. }
  211. WPA_PUT_BE16(length, pos - length - 2);
  212. inc_byte_array(rl->write_seq_num, TLS_SEQ_NUM_LEN);
  213. *out_len = pos - buf;
  214. return 0;
  215. }
  216. /**
  217. * tlsv1_record_receive - TLS record layer: Process a received message
  218. * @rl: Pointer to TLS record layer data
  219. * @in_data: Received data
  220. * @in_len: Length of the received data
  221. * @out_data: Buffer for output data (must be at least as long as in_data)
  222. * @out_len: Set to maximum out_data length by caller; used to return the
  223. * length of the used data
  224. * @alert: Buffer for returning an alert value on failure
  225. * Returns: 0 on success, -1 on failure
  226. *
  227. * This function decrypts the received message, verifies HMAC and TLS record
  228. * layer header.
  229. */
  230. int tlsv1_record_receive(struct tlsv1_record_layer *rl,
  231. const u8 *in_data, size_t in_len,
  232. u8 *out_data, size_t *out_len, u8 *alert)
  233. {
  234. size_t i, rlen, hlen;
  235. u8 padlen;
  236. struct crypto_hash *hmac;
  237. u8 len[2], hash[100];
  238. int force_mac_error = 0;
  239. wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
  240. in_data, in_len);
  241. if (in_len < TLS_RECORD_HEADER_LEN) {
  242. wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu)",
  243. (unsigned long) in_len);
  244. *alert = TLS_ALERT_DECODE_ERROR;
  245. return -1;
  246. }
  247. wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d "
  248. "length %d", in_data[0], in_data[1], in_data[2],
  249. WPA_GET_BE16(in_data + 3));
  250. if (in_data[0] != TLS_CONTENT_TYPE_HANDSHAKE &&
  251. in_data[0] != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC &&
  252. in_data[0] != TLS_CONTENT_TYPE_ALERT &&
  253. in_data[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
  254. wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type 0x%x",
  255. in_data[0]);
  256. *alert = TLS_ALERT_UNEXPECTED_MESSAGE;
  257. return -1;
  258. }
  259. /*
  260. * TLS v1.0 and v1.1 RFCs were not exactly clear on the use of the
  261. * protocol version in record layer. As such, accept any {03,xx} value
  262. * to remain compatible with existing implementations.
  263. */
  264. if (in_data[1] != 0x03) {
  265. wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version "
  266. "%u.%u", in_data[1], in_data[2]);
  267. *alert = TLS_ALERT_PROTOCOL_VERSION;
  268. return -1;
  269. }
  270. rlen = WPA_GET_BE16(in_data + 3);
  271. /* TLSCiphertext must not be more than 2^14+2048 bytes */
  272. if (TLS_RECORD_HEADER_LEN + rlen > 18432) {
  273. wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
  274. (unsigned long) (TLS_RECORD_HEADER_LEN + rlen));
  275. *alert = TLS_ALERT_RECORD_OVERFLOW;
  276. return -1;
  277. }
  278. in_data += TLS_RECORD_HEADER_LEN;
  279. in_len -= TLS_RECORD_HEADER_LEN;
  280. if (rlen > in_len) {
  281. wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included "
  282. "(rlen=%lu > in_len=%lu)",
  283. (unsigned long) rlen, (unsigned long) in_len);
  284. *alert = TLS_ALERT_DECODE_ERROR;
  285. return -1;
  286. }
  287. in_len = rlen;
  288. if (*out_len < in_len) {
  289. wpa_printf(MSG_DEBUG, "TLSv1: Not enough output buffer for "
  290. "processing received record");
  291. *alert = TLS_ALERT_INTERNAL_ERROR;
  292. return -1;
  293. }
  294. if (rl->read_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
  295. size_t plen;
  296. if (crypto_cipher_decrypt(rl->read_cbc, in_data,
  297. out_data, in_len) < 0) {
  298. *alert = TLS_ALERT_DECRYPTION_FAILED;
  299. return -1;
  300. }
  301. plen = in_len;
  302. if (rl->iv_size) {
  303. /*
  304. * TLS v1.0 defines different alert values for various
  305. * failures. That may information to aid in attacks, so
  306. * use the same bad_record_mac alert regardless of the
  307. * issues.
  308. *
  309. * In addition, instead of returning immediately on
  310. * error, run through the MAC check to make timing
  311. * attacks more difficult.
  312. */
  313. /* Verify and remove padding */
  314. if (plen == 0) {
  315. wpa_printf(MSG_DEBUG, "TLSv1: Too short record"
  316. " (no pad)");
  317. force_mac_error = 1;
  318. goto check_mac;
  319. }
  320. padlen = out_data[plen - 1];
  321. if (padlen >= plen) {
  322. wpa_printf(MSG_DEBUG, "TLSv1: Incorrect pad "
  323. "length (%u, plen=%lu) in "
  324. "received record",
  325. padlen, (unsigned long) plen);
  326. force_mac_error = 1;
  327. goto check_mac;
  328. }
  329. for (i = plen - padlen; i < plen; i++) {
  330. if (out_data[i] != padlen) {
  331. wpa_hexdump(MSG_DEBUG,
  332. "TLSv1: Invalid pad in "
  333. "received record",
  334. out_data + plen - padlen,
  335. padlen);
  336. force_mac_error = 1;
  337. goto check_mac;
  338. }
  339. }
  340. plen -= padlen + 1;
  341. }
  342. check_mac:
  343. wpa_hexdump(MSG_MSGDUMP,
  344. "TLSv1: Record Layer - Decrypted data",
  345. out_data, plen);
  346. if (plen < rl->hash_size) {
  347. wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no "
  348. "hash value");
  349. *alert = TLS_ALERT_BAD_RECORD_MAC;
  350. return -1;
  351. }
  352. plen -= rl->hash_size;
  353. hmac = crypto_hash_init(rl->hash_alg, rl->read_mac_secret,
  354. rl->hash_size);
  355. if (hmac == NULL) {
  356. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  357. "to initialize HMAC");
  358. *alert = TLS_ALERT_INTERNAL_ERROR;
  359. return -1;
  360. }
  361. crypto_hash_update(hmac, rl->read_seq_num, TLS_SEQ_NUM_LEN);
  362. /* type + version + length + fragment */
  363. crypto_hash_update(hmac, in_data - TLS_RECORD_HEADER_LEN, 3);
  364. WPA_PUT_BE16(len, plen);
  365. crypto_hash_update(hmac, len, 2);
  366. crypto_hash_update(hmac, out_data, plen);
  367. hlen = sizeof(hash);
  368. if (crypto_hash_finish(hmac, hash, &hlen) < 0) {
  369. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  370. "to calculate HMAC");
  371. *alert = TLS_ALERT_INTERNAL_ERROR;
  372. return -1;
  373. }
  374. if (hlen != rl->hash_size ||
  375. os_memcmp(hash, out_data + plen, hlen) != 0 ||
  376. force_mac_error) {
  377. wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in "
  378. "received message (force_mac_error=%d)",
  379. force_mac_error);
  380. *alert = TLS_ALERT_BAD_RECORD_MAC;
  381. return -1;
  382. }
  383. *out_len = plen;
  384. } else {
  385. os_memcpy(out_data, in_data, in_len);
  386. *out_len = in_len;
  387. }
  388. /* TLSCompressed must not be more than 2^14+1024 bytes */
  389. if (TLS_RECORD_HEADER_LEN + *out_len > 17408) {
  390. wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
  391. (unsigned long) (TLS_RECORD_HEADER_LEN + *out_len));
  392. *alert = TLS_ALERT_RECORD_OVERFLOW;
  393. return -1;
  394. }
  395. inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN);
  396. return 0;
  397. }