1 /* 2 * Copyright (c) 2020 Siddharth Chandrasekaran <siddharth@embedjournal.com> 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef _OSDP_COMMON_H_ 8 #define _OSDP_COMMON_H_ 9 10 #include <mgmt/osdp.h> 11 #include <sys/__assert.h> 12 13 #define OSDP_RESP_TOUT_MS (200) 14 15 #define OSDP_CMD_SLAB_BUF_SIZE \ 16 (sizeof(struct osdp_cmd) * CONFIG_OSDP_PD_COMMAND_QUEUE_SIZE) 17 18 #define ISSET_FLAG(p, f) (((p)->flags & (f)) == (f)) 19 #define SET_FLAG(p, f) ((p)->flags |= (f)) 20 #define CLEAR_FLAG(p, f) ((p)->flags &= ~(f)) 21 22 #define BYTE_0(x) (uint8_t)(((x) >> 0) & 0xFF) 23 #define BYTE_1(x) (uint8_t)(((x) >> 8) & 0xFF) 24 #define BYTE_2(x) (uint8_t)(((x) >> 16) & 0xFF) 25 #define BYTE_3(x) (uint8_t)(((x) >> 24) & 0xFF) 26 27 /* casting helpers */ 28 #define TO_OSDP(p) ((struct osdp *)p) 29 #define TO_CP(p) (((struct osdp *)(p))->cp) 30 #define TO_PD(p, i) (((struct osdp *)(p))->pd + i) 31 #define TO_CTX(p) ((struct osdp *)p->__parent) 32 33 #define GET_CURRENT_PD(p) (TO_CP(p)->current_pd) 34 #define SET_CURRENT_PD(p, i) \ 35 do { \ 36 TO_CP(p)->current_pd = TO_PD(p, i); \ 37 TO_CP(p)->pd_offset = i; \ 38 } while (0) 39 #define PD_MASK(ctx) \ 40 (uint32_t)((1 << (TO_CP(ctx)->num_pd)) - 1) 41 #define AES_PAD_LEN(x) ((x + 16 - 1) & (~(16 - 1))) 42 #define NUM_PD(ctx) (TO_CP(ctx)->num_pd) 43 #define OSDP_COMMAND_DATA_MAX_LEN sizeof(struct osdp_cmd) 44 45 /** 46 * @brief OSDP reserved commands 47 */ 48 #define CMD_POLL 0x60 49 #define CMD_ID 0x61 50 #define CMD_CAP 0x62 51 #define CMD_DIAG 0x63 52 #define CMD_LSTAT 0x64 53 #define CMD_ISTAT 0x65 54 #define CMD_OSTAT 0x66 55 #define CMD_RSTAT 0x67 56 #define CMD_OUT 0x68 57 #define CMD_LED 0x69 58 #define CMD_BUZ 0x6A 59 #define CMD_TEXT 0x6B 60 #define CMD_RMODE 0x6C 61 #define CMD_TDSET 0x6D 62 #define CMD_COMSET 0x6E 63 #define CMD_DATA 0x6F 64 #define CMD_XMIT 0x70 65 #define CMD_PROMPT 0x71 66 #define CMD_SPE 0x72 67 #define CMD_BIOREAD 0x73 68 #define CMD_BIOMATCH 0x74 69 #define CMD_KEYSET 0x75 70 #define CMD_CHLNG 0x76 71 #define CMD_SCRYPT 0x77 72 #define CMD_CONT 0x79 73 #define CMD_ABORT 0x7A 74 #define CMD_MAXREPLY 0x7B 75 #define CMD_MFG 0x80 76 #define CMD_SCDONE 0xA0 77 #define CMD_XWR 0xA1 78 79 /** 80 * @brief OSDP reserved responses 81 */ 82 #define REPLY_ACK 0x40 83 #define REPLY_NAK 0x41 84 #define REPLY_PDID 0x45 85 #define REPLY_PDCAP 0x46 86 #define REPLY_LSTATR 0x48 87 #define REPLY_ISTATR 0x49 88 #define REPLY_OSTATR 0x4A 89 #define REPLY_RSTATR 0x4B 90 #define REPLY_RAW 0x50 91 #define REPLY_FMT 0x51 92 #define REPLY_PRES 0x52 93 #define REPLY_KEYPPAD 0x53 94 #define REPLY_COM 0x54 95 #define REPLY_SCREP 0x55 96 #define REPLY_SPER 0x56 97 #define REPLY_BIOREADR 0x57 98 #define REPLY_BIOMATCHR 0x58 99 #define REPLY_CCRYPT 0x76 100 #define REPLY_RMAC_I 0x78 101 #define REPLY_MFGREP 0x90 102 #define REPLY_BUSY 0x79 103 #define REPLY_XRD 0xB1 104 105 /** 106 * @brief secure block types 107 */ 108 #define SCS_11 0x11 /* CP -> PD -- CMD_CHLNG */ 109 #define SCS_12 0x12 /* PD -> CP -- REPLY_CCRYPT */ 110 #define SCS_13 0x13 /* CP -> PD -- CMD_SCRYPT */ 111 #define SCS_14 0x14 /* PD -> CP -- REPLY_RMAC_I */ 112 113 #define SCS_15 0x15 /* CP -> PD -- packets w MAC w/o ENC */ 114 #define SCS_16 0x16 /* PD -> CP -- packets w MAC w/o ENC */ 115 #define SCS_17 0x17 /* CP -> PD -- packets w MAC w ENC*/ 116 #define SCS_18 0x18 /* PD -> CP -- packets w MAC w ENC*/ 117 118 /* PD Flags */ 119 #define PD_FLAG_SC_CAPABLE 0x00000001 /* PD secure channel capable */ 120 #define PD_FLAG_TAMPER 0x00000002 /* local tamper status */ 121 #define PD_FLAG_POWER 0x00000004 /* local power status */ 122 #define PD_FLAG_R_TAMPER 0x00000008 /* remote tamper status */ 123 #define PD_FLAG_AWAIT_RESP 0x00000020 /* set after command is sent */ 124 #define PD_FLAG_SKIP_SEQ_CHECK 0x00000040 /* disable seq checks (debug) */ 125 #define PD_FLAG_SC_USE_SCBKD 0x00000080 /* in this SC attempt, use SCBKD */ 126 #define PD_FLAG_SC_ACTIVE 0x00000100 /* secure channel is active */ 127 #define PD_FLAG_SC_SCBKD_DONE 0x00000200 /* SCBKD check is done */ 128 #define PD_FLAG_INSTALL_MODE 0x40000000 /* PD is in install mode */ 129 #define PD_FLAG_PD_MODE 0x80000000 /* device is setup as PD */ 130 131 enum osdp_pd_nak_code_e { 132 /** 133 * @brief Dummy 134 */ 135 OSDP_PD_NAK_NONE, 136 /** 137 * @brief Message check character(s) error (bad cksum/crc) 138 */ 139 OSDP_PD_NAK_MSG_CHK, 140 /** 141 * @brief Command length error 142 */ 143 OSDP_PD_NAK_CMD_LEN, 144 /** 145 * @brief Unknown Command Code – Command not implemented by PD 146 */ 147 OSDP_PD_NAK_CMD_UNKNOWN, 148 /** 149 * @brief Unexpected sequence number detected in the header 150 */ 151 OSDP_PD_NAK_SEQ_NUM, 152 /** 153 * @brief Unexpected sequence number detected in the header 154 */ 155 OSDP_PD_NAK_SC_UNSUP, 156 /** 157 * @brief unsupported security block or security conditions not met 158 */ 159 OSDP_PD_NAK_SC_COND, 160 /** 161 * @brief BIO_TYPE not supported 162 */ 163 OSDP_PD_NAK_BIO_TYPE, 164 /** 165 * @brief BIO_FORMAT not supported 166 */ 167 OSDP_PD_NAK_BIO_FMT, 168 /** 169 * @brief Unable to process command record 170 */ 171 OSDP_PD_NAK_RECORD, 172 /** 173 * @brief Dummy 174 */ 175 OSDP_PD_NAK_SENTINEL 176 }; 177 178 enum osdp_pd_state_e { 179 OSDP_PD_STATE_IDLE, 180 OSDP_PD_STATE_SEND_REPLY, 181 OSDP_PD_STATE_ERR, 182 }; 183 184 enum osdp_cp_phy_state_e { 185 OSDP_CP_PHY_STATE_IDLE, 186 OSDP_CP_PHY_STATE_SEND_CMD, 187 OSDP_CP_PHY_STATE_REPLY_WAIT, 188 OSDP_CP_PHY_STATE_WAIT, 189 OSDP_CP_PHY_STATE_ERR, 190 OSDP_CP_PHY_STATE_ERR_WAIT, 191 OSDP_CP_PHY_STATE_CLEANUP, 192 }; 193 194 enum osdp_cp_state_e { 195 OSDP_CP_STATE_INIT, 196 OSDP_CP_STATE_IDREQ, 197 OSDP_CP_STATE_CAPDET, 198 OSDP_CP_STATE_SC_INIT, 199 OSDP_CP_STATE_SC_CHLNG, 200 OSDP_CP_STATE_SC_SCRYPT, 201 OSDP_CP_STATE_SET_SCBK, 202 OSDP_CP_STATE_ONLINE, 203 OSDP_CP_STATE_OFFLINE 204 }; 205 206 enum osdp_pkt_errors_e { 207 OSDP_ERR_PKT_FMT = -1, 208 OSDP_ERR_PKT_WAIT = -2, 209 OSDP_ERR_PKT_SKIP = -3 210 }; 211 212 /** 213 * @brief Various PD capability function codes. 214 */ 215 enum osdp_pd_cap_function_code_e { 216 /** 217 * @brief Dummy. 218 */ 219 OSDP_PD_CAP_UNUSED, 220 221 /** 222 * @brief This function indicates the ability to monitor the status of a 223 * switch using a two-wire electrical connection between the PD and the 224 * switch. The on/off position of the switch indicates the state of an 225 * external device. 226 * 227 * The PD may simply resolve all circuit states to an open/closed 228 * status, or it may implement supervision of the monitoring circuit. 229 * A supervised circuit is able to indicate circuit fault status in 230 * addition to open/closed status. 231 */ 232 OSDP_PD_CAP_CONTACT_STATUS_MONITORING, 233 234 /** 235 * @brief This function provides a switched output, typically in the 236 * form of a relay. The Output has two states: active or inactive. The 237 * Control Panel (CP) can directly set the Output's state, or, if the PD 238 * supports timed operations, the CP can specify a time period for the 239 * activation of the Output. 240 */ 241 OSDP_PD_CAP_OUTPUT_CONTROL, 242 243 /** 244 * @brief This capability indicates the form of the card data is 245 * presented to the Control Panel. 246 */ 247 OSDP_PD_CAP_CARD_DATA_FORMAT, 248 249 /** 250 * @brief This capability indicates the presence of and type of LEDs. 251 */ 252 OSDP_PD_CAP_READER_LED_CONTROL, 253 254 /** 255 * @brief This capability indicates the presence of and type of an 256 * Audible Annunciator (buzzer or similar tone generator) 257 */ 258 OSDP_PD_CAP_READER_AUDIBLE_OUTPUT, 259 260 /** 261 * @brief This capability indicates that the PD supports a text display 262 * emulating character-based display terminals. 263 */ 264 OSDP_PD_CAP_READER_TEXT_OUTPUT, 265 266 /** 267 * @brief This capability indicates that the type of date and time 268 * awareness or time keeping ability of the PD. 269 */ 270 OSDP_PD_CAP_TIME_KEEPING, 271 272 /** 273 * @brief All PDs must be able to support the checksum mode. This 274 * capability indicates if the PD is capable of supporting CRC mode. 275 */ 276 OSDP_PD_CAP_CHECK_CHARACTER_SUPPORT, 277 278 /** 279 * @brief This capability indicates the extent to which the PD supports 280 * communication security (Secure Channel Communication) 281 */ 282 OSDP_PD_CAP_COMMUNICATION_SECURITY, 283 284 /** 285 * @brief This capability indicates the maximum size single message the 286 * PD can receive. 287 */ 288 OSDP_PD_CAP_RECEIVE_BUFFERSIZE, 289 290 /** 291 * @brief This capability indicates the maximum size multi-part message 292 * which the PD can handle. 293 */ 294 OSDP_PD_CAP_LARGEST_COMBINED_MESSAGE_SIZE, 295 296 /** 297 * @brief This capability indicates whether the PD supports the 298 * transparent mode used for communicating directly with a smart card. 299 */ 300 OSDP_PD_CAP_SMART_CARD_SUPPORT, 301 302 /** 303 * @brief This capability indicates the number of credential reader 304 * devices present. Compliance levels are bit fields to be assigned as 305 * needed. 306 */ 307 OSDP_PD_CAP_READERS, 308 309 /** 310 * @brief This capability indicates the ability of the reader to handle 311 * biometric input 312 */ 313 OSDP_PD_CAP_BIOMETRICS, 314 315 /** 316 * @brief Capability Sentinel 317 */ 318 OSDP_PD_CAP_SENTINEL 319 }; 320 321 /** 322 * @brief PD capability structure. Each PD capability has a 3 byte 323 * representation. 324 * 325 * @param function_code One of enum osdp_pd_cap_function_code_e. 326 * @param compliance_level A function_code dependent number that indicates what 327 * the PD can do with this capability. 328 * @param num_items Number of such capability entities in PD. 329 */ 330 struct osdp_pd_cap { 331 uint8_t function_code; 332 uint8_t compliance_level; 333 uint8_t num_items; 334 }; 335 336 /** 337 * @brief PD ID information advertised by the PD. 338 * 339 * @param version 3-bytes IEEE assigned OUI 340 * @param model 1-byte Manufacturer's model number 341 * @param vendor_code 1-Byte Manufacturer's version number 342 * @param serial_number 4-byte serial number for the PD 343 * @param firmware_version 3-byte version (major, minor, build) 344 */ 345 struct osdp_pd_id { 346 int version; 347 int model; 348 uint32_t vendor_code; 349 uint32_t serial_number; 350 uint32_t firmware_version; 351 }; 352 353 struct osdp_channel { 354 /** 355 * @brief pointer to a block of memory that will be passed to the 356 * send/receive method. This is optional and can be left empty. 357 */ 358 void *data; 359 360 /** 361 * @brief pointer to function that copies received bytes into buffer 362 * @param data for use by underlying layers. channel_s::data is passed 363 * @param buf byte array copy incoming data 364 * @param len sizeof `buf`. Can copy utmost `len` bytes into `buf` 365 * 366 * @retval +ve: number of bytes copied on to `bug`. Must be <= `len` 367 * @retval -ve on errors 368 */ 369 int (*recv)(void *data, uint8_t *buf, int maxlen); 370 371 /** 372 * @brief pointer to function that sends byte array into some channel 373 * @param data for use by underlying layers. channel_s::data is passed 374 * @param buf byte array to be sent 375 * @param len number of bytes in `buf` 376 * 377 * @retval +ve: number of bytes sent. must be <= `len` 378 * @retval -ve on errors 379 */ 380 int (*send)(void *data, uint8_t *buf, int len); 381 382 /** 383 * @brief pointer to function that drops all bytes in TX/RX fifo 384 * @param data for use by underlying layers. channel_s::data is passed 385 */ 386 void (*flush)(void *data); 387 }; 388 389 struct osdp_cmd_queue { 390 sys_slist_t queue; 391 struct k_mem_slab slab; 392 uint8_t slab_buf[OSDP_CMD_SLAB_BUF_SIZE]; 393 }; 394 395 struct osdp_notifiers { 396 int (*keypress)(int address, uint8_t key); 397 int (*cardread)(int address, int format, uint8_t *data, int len); 398 }; 399 400 #ifdef CONFIG_OSDP_SC_ENABLED 401 struct osdp_secure_channel { 402 uint8_t scbk[16]; 403 uint8_t s_enc[16]; 404 uint8_t s_mac1[16]; 405 uint8_t s_mac2[16]; 406 uint8_t r_mac[16]; 407 uint8_t c_mac[16]; 408 uint8_t cp_random[8]; 409 uint8_t pd_random[8]; 410 uint8_t pd_client_uid[8]; 411 uint8_t cp_cryptogram[16]; 412 uint8_t pd_cryptogram[16]; 413 }; 414 #endif 415 416 struct osdp_pd { 417 void *__parent; 418 int offset; 419 uint32_t flags; 420 421 /* OSDP specified data */ 422 int baud_rate; 423 int address; 424 int seq_number; 425 struct osdp_pd_cap cap[OSDP_PD_CAP_SENTINEL]; 426 struct osdp_pd_id id; 427 428 /* PD state management */ 429 #ifdef CONFIG_OSDP_MODE_PD 430 enum osdp_pd_state_e state; 431 #else 432 enum osdp_cp_state_e state; 433 enum osdp_cp_phy_state_e phy_state; 434 int64_t phy_tstamp; 435 #endif 436 int64_t tstamp; 437 uint8_t rx_buf[CONFIG_OSDP_UART_BUFFER_LENGTH]; 438 int rx_buf_len; 439 440 int cmd_id; 441 int reply_id; 442 uint8_t cmd_data[OSDP_COMMAND_DATA_MAX_LEN]; 443 444 struct osdp_channel channel; 445 struct osdp_cmd_queue cmd; 446 #ifdef CONFIG_OSDP_SC_ENABLED 447 int64_t sc_tstamp; 448 struct osdp_secure_channel sc; 449 #endif 450 }; 451 452 struct osdp_cp { 453 void *__parent; 454 uint32_t flags; 455 int num_pd; 456 struct osdp_pd *current_pd; /* current operational pd's pointer */ 457 int pd_offset; /* current pd's offset into ctx->pd */ 458 struct osdp_notifiers notifier; 459 }; 460 461 struct osdp { 462 int magic; 463 uint32_t flags; 464 struct osdp_cp *cp; 465 struct osdp_pd *pd; 466 #ifdef CONFIG_OSDP_SC_ENABLED 467 uint8_t sc_master_key[16]; 468 #endif 469 }; 470 471 /* from osdp_phy.c */ 472 int osdp_phy_packet_init(struct osdp_pd *p, uint8_t *buf, int max_len); 473 int osdp_phy_packet_finalize(struct osdp_pd *p, uint8_t *buf, 474 int len, int max_len); 475 int osdp_phy_decode_packet(struct osdp_pd *p, uint8_t *buf, int len); 476 void osdp_phy_state_reset(struct osdp_pd *pd); 477 int osdp_phy_packet_get_data_offset(struct osdp_pd *p, const uint8_t *buf); 478 uint8_t *osdp_phy_packet_get_smb(struct osdp_pd *p, const uint8_t *buf); 479 480 /* from osdp_common.c */ 481 int64_t osdp_millis_now(void); 482 int64_t osdp_millis_since(int64_t last); 483 void osdp_dump(const char *head, uint8_t *buf, int len); 484 uint16_t osdp_compute_crc16(const uint8_t *buf, size_t len); 485 struct osdp_cmd *osdp_cmd_alloc(struct osdp_pd *pd); 486 void osdp_cmd_free(struct osdp_pd *pd, struct osdp_cmd *cmd); 487 void osdp_cmd_enqueue(struct osdp_pd *pd, struct osdp_cmd *cmd); 488 int osdp_cmd_dequeue(struct osdp_pd *pd, struct osdp_cmd **cmd); 489 struct osdp_cmd *osdp_cmd_get_last(struct osdp_pd *pd); 490 491 /* from osdp.c */ 492 struct osdp *osdp_get_ctx(); 493 494 /* from osdp_cp.c */ 495 #ifdef CONFIG_OSDP_MODE_CP 496 int osdp_extract_address(int *address); 497 #endif 498 499 #ifdef CONFIG_OSDP_SC_ENABLED 500 void osdp_encrypt(uint8_t *key, uint8_t *iv, uint8_t *data, int len); 501 void osdp_decrypt(uint8_t *key, uint8_t *iv, uint8_t *data, int len); 502 #endif 503 504 /* from osdp_sc.c */ 505 void osdp_compute_scbk(struct osdp_pd *pd, uint8_t *scbk); 506 void osdp_compute_session_keys(struct osdp *ctx); 507 void osdp_compute_cp_cryptogram(struct osdp_pd *pd); 508 int osdp_verify_cp_cryptogram(struct osdp_pd *pd); 509 void osdp_compute_pd_cryptogram(struct osdp_pd *pd); 510 int osdp_verify_pd_cryptogram(struct osdp_pd *pd); 511 void osdp_compute_rmac_i(struct osdp_pd *pd); 512 int osdp_decrypt_data(struct osdp_pd *pd, int is_cmd, uint8_t *data, int len); 513 int osdp_encrypt_data(struct osdp_pd *pd, int is_cmd, uint8_t *data, int len); 514 int osdp_compute_mac(struct osdp_pd *pd, int is_cmd, 515 const uint8_t *data, int len); 516 void osdp_sc_init(struct osdp_pd *pd); 517 void osdp_fill_random(uint8_t *buf, int len); 518 519 /* must be implemented by CP or PD */ 520 int osdp_setup(struct osdp *ctx, uint8_t *key); 521 void osdp_update(struct osdp *ctx); 522 523 #endif /* _OSDP_COMMON_H_ */ 524