tlsv1_record.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * TLSv1 Record Protocol
  3. * Copyright (c) 2006-2007, 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 "md5.h"
  17. #include "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 to send (with TLS_RECORD_HEADER_LEN octets reserved in the
  122. * beginning for record layer to fill in; payload filled in after this and
  123. * extra space in the end for HMAC).
  124. * @buf_size: Maximum buf size
  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, size_t payload_len, size_t *out_len)
  134. {
  135. u8 *pos, *ct_start, *length, *payload;
  136. struct crypto_hash *hmac;
  137. size_t clen;
  138. pos = buf;
  139. /* ContentType type */
  140. ct_start = pos;
  141. *pos++ = content_type;
  142. /* ProtocolVersion version */
  143. WPA_PUT_BE16(pos, TLS_VERSION);
  144. pos += 2;
  145. /* uint16 length */
  146. length = pos;
  147. WPA_PUT_BE16(length, payload_len);
  148. pos += 2;
  149. /* opaque fragment[TLSPlaintext.length] */
  150. payload = pos;
  151. pos += payload_len;
  152. if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
  153. hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
  154. rl->hash_size);
  155. if (hmac == NULL) {
  156. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  157. "to initialize HMAC");
  158. return -1;
  159. }
  160. crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
  161. /* type + version + length + fragment */
  162. crypto_hash_update(hmac, ct_start, pos - ct_start);
  163. clen = buf + buf_size - pos;
  164. if (clen < rl->hash_size) {
  165. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
  166. "enough room for MAC");
  167. crypto_hash_finish(hmac, NULL, NULL);
  168. return -1;
  169. }
  170. if (crypto_hash_finish(hmac, pos, &clen) < 0) {
  171. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  172. "to calculate HMAC");
  173. return -1;
  174. }
  175. wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Write HMAC",
  176. pos, clen);
  177. pos += clen;
  178. if (rl->iv_size) {
  179. size_t len = pos - payload;
  180. size_t pad;
  181. pad = (len + 1) % rl->iv_size;
  182. if (pad)
  183. pad = rl->iv_size - pad;
  184. if (pos + pad + 1 > buf + buf_size) {
  185. wpa_printf(MSG_DEBUG, "TLSv1: No room for "
  186. "block cipher padding");
  187. return -1;
  188. }
  189. os_memset(pos, pad, pad + 1);
  190. pos += pad + 1;
  191. }
  192. if (crypto_cipher_encrypt(rl->write_cbc, payload,
  193. payload, pos - payload) < 0)
  194. return -1;
  195. }
  196. WPA_PUT_BE16(length, pos - length - 2);
  197. inc_byte_array(rl->write_seq_num, TLS_SEQ_NUM_LEN);
  198. *out_len = pos - buf;
  199. return 0;
  200. }
  201. /**
  202. * tlsv1_record_receive - TLS record layer: Process a received message
  203. * @rl: Pointer to TLS record layer data
  204. * @in_data: Received data
  205. * @in_len: Length of the received data
  206. * @out_data: Buffer for output data (must be at least as long as in_data)
  207. * @out_len: Set to maximum out_data length by caller; used to return the
  208. * length of the used data
  209. * @alert: Buffer for returning an alert value on failure
  210. * Returns: 0 on success, -1 on failure
  211. *
  212. * This function decrypts the received message, verifies HMAC and TLS record
  213. * layer header.
  214. */
  215. int tlsv1_record_receive(struct tlsv1_record_layer *rl,
  216. const u8 *in_data, size_t in_len,
  217. u8 *out_data, size_t *out_len, u8 *alert)
  218. {
  219. size_t i, rlen, hlen;
  220. u8 padlen;
  221. struct crypto_hash *hmac;
  222. u8 len[2], hash[100];
  223. wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
  224. in_data, in_len);
  225. if (in_len < TLS_RECORD_HEADER_LEN) {
  226. wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu)",
  227. (unsigned long) in_len);
  228. *alert = TLS_ALERT_DECODE_ERROR;
  229. return -1;
  230. }
  231. wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d "
  232. "length %d", in_data[0], in_data[1], in_data[2],
  233. WPA_GET_BE16(in_data + 3));
  234. if (in_data[0] != TLS_CONTENT_TYPE_HANDSHAKE &&
  235. in_data[0] != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC &&
  236. in_data[0] != TLS_CONTENT_TYPE_ALERT &&
  237. in_data[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
  238. wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type 0x%x",
  239. in_data[0]);
  240. *alert = TLS_ALERT_UNEXPECTED_MESSAGE;
  241. return -1;
  242. }
  243. if (WPA_GET_BE16(in_data + 1) != TLS_VERSION) {
  244. wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version "
  245. "%d.%d", in_data[1], in_data[2]);
  246. *alert = TLS_ALERT_PROTOCOL_VERSION;
  247. return -1;
  248. }
  249. rlen = WPA_GET_BE16(in_data + 3);
  250. /* TLSCiphertext must not be more than 2^14+2048 bytes */
  251. if (TLS_RECORD_HEADER_LEN + rlen > 18432) {
  252. wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
  253. (unsigned long) (TLS_RECORD_HEADER_LEN + rlen));
  254. *alert = TLS_ALERT_RECORD_OVERFLOW;
  255. return -1;
  256. }
  257. in_data += TLS_RECORD_HEADER_LEN;
  258. in_len -= TLS_RECORD_HEADER_LEN;
  259. if (rlen > in_len) {
  260. wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included "
  261. "(rlen=%lu > in_len=%lu)",
  262. (unsigned long) rlen, (unsigned long) in_len);
  263. *alert = TLS_ALERT_DECODE_ERROR;
  264. return -1;
  265. }
  266. in_len = rlen;
  267. if (*out_len < in_len) {
  268. wpa_printf(MSG_DEBUG, "TLSv1: Not enough output buffer for "
  269. "processing received record");
  270. *alert = TLS_ALERT_INTERNAL_ERROR;
  271. return -1;
  272. }
  273. os_memcpy(out_data, in_data, in_len);
  274. *out_len = in_len;
  275. if (rl->read_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
  276. if (crypto_cipher_decrypt(rl->read_cbc, out_data,
  277. out_data, in_len) < 0) {
  278. *alert = TLS_ALERT_DECRYPTION_FAILED;
  279. return -1;
  280. }
  281. if (rl->iv_size) {
  282. if (in_len == 0) {
  283. wpa_printf(MSG_DEBUG, "TLSv1: Too short record"
  284. " (no pad)");
  285. *alert = TLS_ALERT_DECODE_ERROR;
  286. return -1;
  287. }
  288. padlen = out_data[in_len - 1];
  289. if (padlen >= in_len) {
  290. wpa_printf(MSG_DEBUG, "TLSv1: Incorrect pad "
  291. "length (%u, in_len=%lu) in "
  292. "received record",
  293. padlen, (unsigned long) in_len);
  294. *alert = TLS_ALERT_DECRYPTION_FAILED;
  295. return -1;
  296. }
  297. for (i = in_len - padlen; i < in_len; i++) {
  298. if (out_data[i] != padlen) {
  299. wpa_hexdump(MSG_DEBUG,
  300. "TLSv1: Invalid pad in "
  301. "received record",
  302. out_data + in_len - padlen,
  303. padlen);
  304. *alert = TLS_ALERT_DECRYPTION_FAILED;
  305. return -1;
  306. }
  307. }
  308. *out_len -= padlen + 1;
  309. }
  310. wpa_hexdump(MSG_MSGDUMP,
  311. "TLSv1: Record Layer - Decrypted data",
  312. out_data, in_len);
  313. if (*out_len < rl->hash_size) {
  314. wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no "
  315. "hash value");
  316. *alert = TLS_ALERT_INTERNAL_ERROR;
  317. return -1;
  318. }
  319. *out_len -= rl->hash_size;
  320. hmac = crypto_hash_init(rl->hash_alg, rl->read_mac_secret,
  321. rl->hash_size);
  322. if (hmac == NULL) {
  323. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  324. "to initialize HMAC");
  325. *alert = TLS_ALERT_INTERNAL_ERROR;
  326. return -1;
  327. }
  328. crypto_hash_update(hmac, rl->read_seq_num, TLS_SEQ_NUM_LEN);
  329. /* type + version + length + fragment */
  330. crypto_hash_update(hmac, in_data - TLS_RECORD_HEADER_LEN, 3);
  331. WPA_PUT_BE16(len, *out_len);
  332. crypto_hash_update(hmac, len, 2);
  333. crypto_hash_update(hmac, out_data, *out_len);
  334. hlen = sizeof(hash);
  335. if (crypto_hash_finish(hmac, hash, &hlen) < 0) {
  336. wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
  337. "to calculate HMAC");
  338. return -1;
  339. }
  340. if (hlen != rl->hash_size ||
  341. os_memcmp(hash, out_data + *out_len, hlen) != 0) {
  342. wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in "
  343. "received message");
  344. *alert = TLS_ALERT_BAD_RECORD_MAC;
  345. return -1;
  346. }
  347. }
  348. /* TLSCompressed must not be more than 2^14+1024 bytes */
  349. if (TLS_RECORD_HEADER_LEN + *out_len > 17408) {
  350. wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
  351. (unsigned long) (TLS_RECORD_HEADER_LEN + *out_len));
  352. *alert = TLS_ALERT_RECORD_OVERFLOW;
  353. return -1;
  354. }
  355. inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN);
  356. return 0;
  357. }