tizen 2.3 release
[framework/connectivity/bluez.git] / tools / parser / smp.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2011  Intel Corporation.
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "parser.h"
35
36 /* SMP command codes */
37 #define SMP_CMD_PAIRING_REQ     0x01
38 #define SMP_CMD_PAIRING_RESP    0x02
39 #define SMP_CMD_PAIRING_CONFIRM 0x03
40 #define SMP_CMD_PAIRING_RANDOM  0x04
41 #define SMP_CMD_PAIRING_FAILED  0x05
42 #define SMP_CMD_ENCRYPT_INFO    0x06
43 #define SMP_CMD_MASTER_IDENT    0x07
44 #define SMP_CMD_IDENT_INFO      0X08
45 #define SMP_CMD_IDENT_ADDR_INFO 0x09
46 #define SMP_CMD_SIGN_INFO       0x0a
47 #define SMP_CMD_SECURITY_REQ    0x0b
48
49 /* IO Capabilities values */
50 #define SMP_IO_DISPLAY_ONLY     0x00
51 #define SMP_IO_DISPLAY_YESNO    0x01
52 #define SMP_IO_KEYBOARD_ONLY    0x02
53 #define SMP_IO_NO_INPUT_OUTPUT  0x03
54 #define SMP_IO_KEYBOARD_DISPLAY 0x04
55
56 /* OOB Data Present Values */
57 #define SMP_OOB_NOT_PRESENT     0x00
58 #define SMP_OOB_PRESENT         0x01
59
60 #define SMP_DIST_ENC_KEY        0x01
61 #define SMP_DIST_ID_KEY         0x02
62 #define SMP_DIST_SIGN           0x04
63
64 #define SMP_AUTH_NONE           0x00
65 #define SMP_AUTH_BONDING        0x01
66 #define SMP_AUTH_MITM           0x04
67
68 #define SMP_REASON_PASSKEY_ENTRY_FAILED         0x01
69 #define SMP_REASON_OOB_NOT_AVAIL                0x02
70 #define SMP_REASON_AUTH_REQUIREMENTS            0x03
71 #define SMP_REASON_CONFIRM_FAILED               0x04
72 #define SMP_REASON_PAIRING_NOTSUPP              0x05
73 #define SMP_REASON_ENC_KEY_SIZE                 0x06
74 #define SMP_REASON_CMD_NOTSUPP                  0x07
75 #define SMP_REASON_UNSPECIFIED                  0x08
76 #define SMP_REASON_REPEATED_ATTEMPTS            0x09
77
78 static const char *smpcmd2str(uint8_t cmd)
79 {
80         switch (cmd) {
81         case SMP_CMD_PAIRING_REQ:
82                 return "Pairing Request";
83         case SMP_CMD_PAIRING_RESP:
84                 return "Pairing Response";
85         case SMP_CMD_PAIRING_CONFIRM:
86                 return "Pairing Confirm";
87         case SMP_CMD_PAIRING_RANDOM:
88                 return "Pairing Random";
89         case SMP_CMD_PAIRING_FAILED:
90                 return "Pairing Failed";
91         case SMP_CMD_ENCRYPT_INFO:
92                 return "Encryption Information";
93         case SMP_CMD_MASTER_IDENT:
94                 return "Master Identification";
95         case SMP_CMD_IDENT_INFO:
96                 return "Identity Information";
97         case SMP_CMD_IDENT_ADDR_INFO:
98                 return "Identity Address Information";
99         case SMP_CMD_SIGN_INFO:
100                 return "Signing Information";
101         case SMP_CMD_SECURITY_REQ:
102                 return "Security Request";
103         default:
104                 return "Unknown";
105         }
106 }
107
108 static const char *smpio2str(uint8_t cap)
109 {
110         switch(cap) {
111         case SMP_IO_DISPLAY_ONLY:
112                 return "DisplayOnly";
113         case SMP_IO_DISPLAY_YESNO:
114                 return "DisplayYesNo";
115         case SMP_IO_KEYBOARD_ONLY:
116                 return "KeyboardOnly";
117         case SMP_IO_NO_INPUT_OUTPUT:
118                 return "NoInputNoOutput";
119         case SMP_IO_KEYBOARD_DISPLAY:
120                 return "KeyboardDisplay";
121         default:
122                 return "Unkown";
123         }
124 }
125
126 static const char *smpreason2str(uint8_t reason)
127 {
128         switch (reason) {
129         case SMP_REASON_PASSKEY_ENTRY_FAILED:
130                 return "Passkey Entry Failed";
131         case SMP_REASON_OOB_NOT_AVAIL:
132                 return "OOB Not Available";
133         case SMP_REASON_AUTH_REQUIREMENTS:
134                 return "Authentication Requirements";
135         case SMP_REASON_CONFIRM_FAILED:
136                 return "Confirm Value Failed";
137         case SMP_REASON_PAIRING_NOTSUPP:
138                 return "Pairing Not Supported";
139         case SMP_REASON_ENC_KEY_SIZE:
140                 return "Encryption Key Size";
141         case SMP_REASON_CMD_NOTSUPP:
142                 return "Command Not Supported";
143         case SMP_REASON_UNSPECIFIED:
144                 return "Unspecified Reason";
145         case SMP_REASON_REPEATED_ATTEMPTS:
146                 return "Repeated Attempts";
147         default:
148                 return "Unkown";
149         }
150 }
151
152 static void smp_cmd_pairing_dump(int level, struct frame *frm)
153 {
154         uint8_t cap = get_u8(frm);
155         uint8_t oob = get_u8(frm);
156         uint8_t auth = get_u8(frm);
157         uint8_t key_size = get_u8(frm);
158         uint8_t int_dist = get_u8(frm);
159         uint8_t resp_dist = get_u8(frm);
160
161         p_indent(level, frm);
162         printf("capability 0x%2.2x oob 0x%2.2x auth req 0x%2.2x\n", cap, oob,
163                                                                         auth);
164
165         p_indent(level , frm);
166         printf("max key size 0x%2.2x init key dist 0x%2.2x "
167                 "resp key dist 0x%2.2x\n", key_size, int_dist, resp_dist);
168
169         p_indent(level , frm);
170         printf("Capability: %s (OOB data %s)\n", smpio2str(cap),
171                                 oob == 0x00 ? "not present" : "available");
172
173         p_indent(level , frm);
174         printf("Authentication: %s (%s)\n",
175                         auth & SMP_AUTH_BONDING ? "Bonding" : "No Bonding",
176                         auth & SMP_AUTH_MITM ? "MITM Protection" :
177                         "No MITM Protection");
178
179         p_indent(level , frm);
180         printf("Initiator Key Distribution:  %s %s %s\n",
181                         int_dist & SMP_DIST_ENC_KEY ? "LTK" : "",
182                         int_dist & SMP_DIST_ID_KEY ? "IRK" : "",
183                         int_dist & SMP_DIST_SIGN ? "CSRK" : "");
184
185         p_indent(level , frm);
186         printf("Responder Key Distribution:  %s %s %s\n",
187                         resp_dist & SMP_DIST_ENC_KEY ? "LTK" : "",
188                         resp_dist & SMP_DIST_ID_KEY ? "IRK" : "",
189                         resp_dist & SMP_DIST_SIGN ? "CSRK" : "");
190 }
191
192 static void smp_cmd_pairing_confirm_dump(int level, struct frame *frm)
193 {
194         int i;
195
196         p_indent(level, frm);
197         printf("key ");
198         for (i = 0; i < 16; i++)
199                 printf("%2.2x", get_u8(frm));
200         printf("\n");
201 }
202
203 static void smp_cmd_pairing_random_dump(int level, struct frame *frm)
204 {
205         int i;
206
207         p_indent(level, frm);
208         printf("random ");
209         for (i = 0; i < 16; i++)
210                 printf("%2.2x", get_u8(frm));
211         printf("\n");
212 }
213
214 static void smp_cmd_pairing_failed_dump(int level, struct frame *frm)
215 {
216         uint8_t reason = get_u8(frm);
217
218         p_indent(level, frm);
219         printf("reason 0x%2.2x\n", reason);
220
221         p_indent(level, frm);
222         printf("Reason %s\n", smpreason2str(reason));
223 }
224
225 static void smp_cmd_encrypt_info_dump(int level, struct frame *frm)
226 {
227         int i;
228
229         p_indent(level, frm);
230         printf("LTK ");
231         for (i = 0; i < 16; i++)
232                 printf("%2.2x", get_u8(frm));
233         printf("\n");
234 }
235
236 static void smp_cmd_master_ident_dump(int level, struct frame *frm)
237 {
238         uint16_t ediv = btohs(htons(get_u16(frm)));
239         int i;
240
241         p_indent(level, frm);
242         printf("EDIV 0x%4.4x ", ediv);
243
244         printf("Rand 0x");
245         for (i = 0; i < 8; i++)
246                 printf("%2.2x", get_u8(frm));
247         printf("\n");
248 }
249
250 static void smp_cmd_ident_info_dump(int level, struct frame *frm)
251 {
252         int i;
253
254         p_indent(level, frm);
255         printf("IRK ");
256         for (i = 0; i < 16; i++)
257                 printf("%2.2x", get_u8(frm));
258         printf("\n");
259 }
260
261 static void smp_cmd_ident_addr_info_dump(int level, struct frame *frm)
262 {
263         uint8_t type = get_u8(frm);
264         char addr[18];
265
266         p_indent(level, frm);
267         p_ba2str((bdaddr_t *) frm, addr);
268         printf("bdaddr %s (%s)\n", addr, type == 0x00 ? "Public" : "Random");
269 }
270
271 static void smp_cmd_sign_info_dump(int level, struct frame *frm)
272 {
273         int i;
274
275         p_indent(level, frm);
276         printf("CSRK ");
277         for (i = 0; i < 16; i++)
278                 printf("%2.2x", get_u8(frm));
279         printf("\n");
280 }
281
282 static void smp_cmd_security_req_dump(int level, struct frame *frm)
283 {
284         uint8_t auth = get_u8(frm);
285
286         p_indent(level, frm);
287         printf("auth req 0x%2.2x\n", auth);
288 }
289
290 void smp_dump(int level, struct frame *frm)
291 {
292         uint8_t cmd;
293
294         cmd = get_u8(frm);
295
296         p_indent(level, frm);
297         printf("SMP: %s (0x%.2x)\n", smpcmd2str(cmd), cmd);
298
299         switch (cmd) {
300         case SMP_CMD_PAIRING_REQ:
301                 smp_cmd_pairing_dump(level + 1, frm);
302                 break;
303         case SMP_CMD_PAIRING_RESP:
304                 smp_cmd_pairing_dump(level + 1, frm);
305                 break;
306         case SMP_CMD_PAIRING_CONFIRM:
307                 smp_cmd_pairing_confirm_dump(level + 1, frm);
308                 break;
309         case SMP_CMD_PAIRING_RANDOM:
310                 smp_cmd_pairing_random_dump(level + 1, frm);
311                 break;
312         case SMP_CMD_PAIRING_FAILED:
313                 smp_cmd_pairing_failed_dump(level + 1, frm);
314                 break;
315         case SMP_CMD_ENCRYPT_INFO:
316                 smp_cmd_encrypt_info_dump(level + 1, frm);
317                 break;
318         case SMP_CMD_MASTER_IDENT:
319                 smp_cmd_master_ident_dump(level + 1, frm);
320                 break;
321         case SMP_CMD_IDENT_INFO:
322                 smp_cmd_ident_info_dump(level + 1, frm);
323                 break;
324         case SMP_CMD_IDENT_ADDR_INFO:
325                 smp_cmd_ident_addr_info_dump(level + 1, frm);
326                 break;
327         case SMP_CMD_SIGN_INFO:
328                 smp_cmd_sign_info_dump(level + 1, frm);
329                 break;
330         case SMP_CMD_SECURITY_REQ:
331                 smp_cmd_security_req_dump(level + 1, frm);
332                 break;
333         default:
334                 raw_dump(level, frm);
335         }
336 }