Come back is now!

生活哲学随笔
本文分享了一些关于人际关系和生活的见解,包括如何面对他人的好奇、理解爱情的本质及衡量感情投入的价值等,作者还表达了对新的一年的期待。

1. 不要试图去躲避某些对你好奇的人,因为如果他们从别的认识你的人那里去了解你,你就会成为被编排的对象,以讹传讹或神乎其神。
2. 一切有形之物都会损坏。
3. 不要要求你的恋人,懂得去知足。
4. 你和世界上所有的人只隔有四个人的距离。
5. 不要用尝试的方法对待爱情。
6. 爱人的真谛也许只在于他会把手中仅存的苹果的有虫的一半分给你。
7. 一个有一万块钱的人为你花一千元你只不过占有了他的十分之一,而一个有十块钱的人为你花了十块钱你则占有了它的百分之百。

今年不知道是怎么了,觉得挺不顺的,但是中国人还是要过新年,希望我这不是一年的开头不顺,而是一年的结尾不顺,期待明年吧。 另附上面的理念,人活着总得有自己的理念。

另外,我的 Blog 现在允许匿名发表评论了,又像以前一样了,希望大家可以在这里留下些足迹。

/* * Copyright (c) 2019-2024 Siddharth Chandrasekaran <sidcha.dev@gmail.com> * * SPDX-License-Identifier: Apache-2.0 */ #include "osdp_common.h" #include "osdp_diag.h" #define OSDP_PKT_MARK 0xFF #define OSDP_PKT_SOM 0x53 #define PKT_CONTROL_SQN 0x03 #define PKT_CONTROL_CRC 0x04 #define PKT_CONTROL_SCB 0x08 #define PKT_TRACE_MANGLED 0x80 PACK(struct osdp_packet_header { uint8_t som; uint8_t pd_address; uint8_t len_lsb; uint8_t len_msb; uint8_t control; uint8_t data[]; }); static void print_hex(unsigned char *buffer, int len) { int i; for(i = 0;i < len; i++) { if(buffer[i] <= 0x0F) printf("0x%x", buffer[i]); else printf("%x", buffer[i]); } printf("\n"); return; } static inline bool packet_has_mark(struct osdp_pd *pd) { return ISSET_FLAG(pd, PD_FLAG_PKT_HAS_MARK); } static int osdp_channel_send(struct osdp_pd *pd, uint8_t *buf, int len) { int sent, total_sent = 0; /* flush rx to remove any invalid data. */ if (pd->channel.flush) { pd->channel.flush(pd->channel.data); } do { /* send can block; so be greedy */ sent = pd->channel.send(pd->channel.data, buf + total_sent, len - total_sent); if (sent <= 0) { break; } total_sent += sent; } while (total_sent < len); if(ISSET_FLAG(pd, PD_FLAG_PRINT_MASSAGE)) { LOG_ERR("[SENDBUF]:"); print_hex(buf, total_sent); } return total_sent; } static int osdp_channel_receive(struct osdp_pd *pd) { uint8_t buf[64]; int recv, total_recv = 0; #ifdef UNIT_TESTING /** * Some unit tests don't define pd->channel.recv and directly fill * pd->packet_buf to test if everything else work correctly. */ if (!pd->channel.recv) { return 0; } #endif do { recv = pd->channel.recv(pd->channel.data, buf, sizeof(buf)); if (recv <= 0) { break; } if (osdp_rb_push_buf(&pd->rx_rb, buf, recv) != recv) { LOG_EM("RX ring buffer overflow!"); return -1; } total_recv += recv; } while (recv == sizeof(buf)); #if 0 if(pd->address == 0 && total_recv != 0) { LOG_ERR("packet buf:"); print_hex(buf, total_recv); if(pd->rx_rb.head == pd->rx_rb.tail) { LOG_ERR("push buffer again."); osdp_rb_push_buf(&pd->rx_rb, buf, total_recv); } } #endif if(ISSET_FLAG(pd, PD_FLAG_PRINT_MASSAGE) && total_recv != 0) { LOG_ERR("recvie packet buf:"); print_hex(buf, total_recv); } return total_recv; } uint8_t osdp_compute_checksum(uint8_t *msg, int length) { uint8_t checksum = 0; int i, whole_checksum; whole_checksum = 0; for (i = 0; i < length; i++) { whole_checksum += msg[i]; checksum = ~(0xff & whole_checksum) + 1; } return checksum; } static int osdp_phy_get_seq_number(struct osdp_pd *pd, int do_inc) { /* pd->seq_num is set to -1 to reset phy cmd state */ if (do_inc) { pd->seq_number += 1; if (pd->seq_number > 3) { pd->seq_number = 1; } } return pd->seq_number & PKT_CONTROL_SQN; } int osdp_phy_packet_get_data_offset(struct osdp_pd *pd, const uint8_t *buf) { int sb_len = 0, mark_byte_len = 0; struct osdp_packet_header *pkt; ARG_UNUSED(pd); if (packet_has_mark(pd)) { mark_byte_len = 1; buf += 1; } pkt = (struct osdp_packet_header *)buf; if (pkt->control & PKT_CONTROL_SCB) { sb_len = pkt->data[0]; } return mark_byte_len + sizeof(struct osdp_packet_header) + sb_len; } uint8_t *osdp_phy_packet_get_smb(struct osdp_pd *pd, const uint8_t *buf) { struct osdp_packet_header *pkt; pkt = (struct osdp_packet_header *)(buf + packet_has_mark(pd)); return (pkt->control & PKT_CONTROL_SCB) ? pkt->data : NULL; } int osdp_phy_in_sc_handshake(int is_reply, int id) { if (is_reply) { return (id == REPLY_CCRYPT || id == REPLY_RMAC_I); } else { return (id == CMD_CHLNG || id == CMD_SCRYPT); } } int osdp_phy_packet_init(struct osdp_pd *pd, uint8_t *buf, int max_len) { int id, scb_len = 0; struct osdp_packet_header *pkt; if (max_len < OSDP_MINIMUM_PACKET_SIZE) { LOG_ERR("packet_init: packet size too small"); return OSDP_ERR_PKT_FMT; } /** * In PD mode just follow what we received from CP. In CP mode, as we * initiate the transaction, choose based on CONFIG_OSDP_SKIP_MARK_BYTE. */ if ((is_pd_mode(pd) && packet_has_mark(pd)) || (is_cp_mode(pd) && !ISSET_FLAG(pd, PD_FLAG_PKT_SKIP_MARK))) { buf[0] = OSDP_PKT_MARK; buf++; SET_FLAG(pd, PD_FLAG_PKT_HAS_MARK); } /* Fill packet header */ pkt = (struct osdp_packet_header *)buf; pkt->som = OSDP_PKT_SOM; pkt->pd_address = pd->address & 0x7F; /* Use only the lower 7 bits */ if (ISSET_FLAG(pd, PD_FLAG_PKT_BROADCAST)) { pkt->pd_address = 0x7F; CLEAR_FLAG(pd, PD_FLAG_PKT_BROADCAST); } /* PD must reply with MSB of it's address set */ if (is_pd_mode(pd)) { pkt->pd_address |= 0x80; id = pd->reply_id; } else { id = pd->cmd_id; } pkt->control = osdp_phy_get_seq_number(pd, is_cp_mode(pd)); pkt->control |= PKT_CONTROL_CRC; if (sc_is_active(pd)) { pkt->control |= PKT_CONTROL_SCB; pkt->data[0] = scb_len = 2; pkt->data[1] = SCS_15; } else if (osdp_phy_in_sc_handshake(is_pd_mode(pd), id)) { pkt->control |= PKT_CONTROL_SCB; pkt->data[0] = scb_len = 3; pkt->data[1] = SCS_11; } return (packet_has_mark(pd) + sizeof(struct osdp_packet_header) + scb_len); } static int osdp_phy_packet_finalize(struct osdp_pd *pd, uint8_t *buf, int len, int max_len) { uint16_t crc16; struct osdp_packet_header *pkt; uint8_t *data; int data_len; /* Do a sanity check only; we expect header to be pre-filled */ if ((unsigned long)len <= sizeof(struct osdp_packet_header)) { LOG_ERR("PKT_F: Invalid header"); return OSDP_ERR_PKT_FMT; } if (packet_has_mark(pd)) { if (buf[0] != OSDP_PKT_MARK) { LOG_ERR("PKT_F: MARK validation failed! ID: 0x%02x", is_cp_mode(pd) ? pd->cmd_id : pd->reply_id); return OSDP_ERR_PKT_FMT; } /* temporarily get rid of mark byte */ buf += 1; len -= 1; max_len -= 1; } pkt = (struct osdp_packet_header *)buf; if (pkt->som != OSDP_PKT_SOM) { LOG_ERR("PKT_F: header SOM validation failed! ID: 0x%02x", is_cp_mode(pd) ? pd->cmd_id : pd->reply_id); return OSDP_ERR_PKT_FMT; } /* len: with 2 byte CRC */ pkt->len_lsb = BYTE_0(len + 2); pkt->len_msb = BYTE_1(len + 2); if (is_data_trace_enabled(pd)) { uint8_t control; /** * We can potentially avoid having to set PKT_TRACE_MANGLED * here if we can get the dissector accept fully formed SCB * but non-encrypted data block. But that might lead to the * dissector parsing malformed packets as valid ones. * * See the counterpart of this in osdp_phy_decode_packet() for * more details. */ control = pkt->control; pkt->control |= PKT_TRACE_MANGLED; osdp_capture_packet(pd, (uint8_t *)pkt, len + 2); pkt->control = control; } if (sc_is_active(pd) && pkt->control & PKT_CONTROL_SCB && pkt->data[1] >= SCS_15) { if (pkt->data[1] == SCS_17 || pkt->data[1] == SCS_18) { /** * Only the data portion of message (after id byte) * is encrypted. While (en)decrypting, we must skip * header, security block, and cmd/reply ID byte. * * Note: if cmd/reply has no data, we must set type to * SCS_15/SCS_16 and send them. */ data = pkt->data + pkt->data[0] + 1; data_len = len - (sizeof(struct osdp_packet_header) + pkt->data[0] + 1); len -= data_len; /** * check if the passed buffer can hold the encrypted * data where length may be rounded up to the nearest * 16 byte block boundary. */ if (AES_PAD_LEN(data_len + 1) > max_len) { /* data_len + 1 for OSDP_SC_EOM_MARKER */ goto out_of_space_error; } len += osdp_encrypt_data(pd, is_cp_mode(pd), data, data_len); } /* len: with 4bytes MAC; with 2 byte CRC; without 1 byte mark */ if (len + 4 > max_len) { goto out_of_space_error; } /* len: with 2 byte CRC; with 4 byte MAC */ pkt->len_lsb = BYTE_0(len + 2 + 4); pkt->len_msb = BYTE_1(len + 2 + 4); /* compute and extend the buf with 4 MAC bytes */ osdp_compute_mac(pd, is_cp_mode(pd), buf, len); data = is_cp_mode(pd) ? pd->sc.c_mac : pd->sc.r_mac; memcpy(buf + len, data, 4); len += 4; } /* fill crc16 */ if (len + 2 > max_len) { goto out_of_space_error; } crc16 = osdp_compute_crc16(buf, len); buf[len + 0] = BYTE_0(crc16); buf[len + 1] = BYTE_1(crc16); len += 2; return len + packet_has_mark(pd); out_of_space_error: LOG_ERR("PKT_F: Out of buffer space! CMD(%02x)", pd->cmd_id); return OSDP_ERR_PKT_FMT; } int osdp_phy_send_packet(struct osdp_pd *pd, uint8_t *buf, int len, int max_len) { int ret; /* if it has been more than TOUT_MS, then CP will not process. Do not send */ if(is_pd_mode(pd) && (osdp_millis_since(pd->tstamp) > OSDP_RESP_TOUT_MS)) { return OSDP_ERR_PKT_BUSY; } /* finalize packet */ len = osdp_phy_packet_finalize(pd, buf, len, max_len); if (len < 0) { return OSDP_ERR_PKT_BUILD; } if (is_packet_trace_enabled(pd)) { osdp_capture_packet(pd, buf, len); } ret = osdp_channel_send(pd, buf, len); if (ret != len) { LOG_ERR("Channel send for %d bytes failed! ret: %d", len, ret); return OSDP_ERR_PKT_BUILD; } return OSDP_ERR_PKT_NONE; } static bool phy_rescan_packet_buf(struct osdp_pd *pd) { unsigned long j = packet_has_mark(pd); unsigned long i = j + 1; /* +1 to skip current SoM */ while (i < pd->packet_buf_len && pd->packet_buf[i] != OSDP_PKT_SOM) { i++; } if (i < pd->packet_buf_len) { /* found another SoM; move the rest of the bytes down */ if (i && pd->packet_buf[i - 1] == OSDP_PKT_MARK) { pd->packet_buf[0] = OSDP_PKT_MARK; j = 1; SET_FLAG(pd, PD_FLAG_PKT_HAS_MARK); } else { j = 0; CLEAR_FLAG(pd, PD_FLAG_PKT_HAS_MARK); } while (i < pd->packet_buf_len) { pd->packet_buf[j++] = pd->packet_buf[i++]; } pd->packet_buf_len = j; return true; } /* nothing found, discarded all */ pd->packet_buf_len = 0; return false; } static int phy_check_header(struct osdp_pd *pd) { unsigned long pkt_len; int len; struct osdp_packet_header *pkt; uint8_t cur_byte = 0, prev_byte = 0; uint8_t *buf = pd->packet_buf; /* Scan for packet start */ while (pd->packet_buf_len == 0) { if (osdp_rb_pop(&pd->rx_rb, &cur_byte)) { if(ISSET_FLAG(pd, PD_FLAG_PRINT_MASSAGE)) LOG_ERR("NO data now."); return OSDP_ERR_PKT_NO_DATA; } if (cur_byte == OSDP_PKT_SOM) { if (prev_byte == OSDP_PKT_MARK) { buf[0] = OSDP_PKT_MARK; buf[1] = OSDP_PKT_SOM; pd->packet_buf_len = 2; SET_FLAG(pd, PD_FLAG_PKT_HAS_MARK); } else { buf[0] = OSDP_PKT_SOM; pd->packet_buf_len = 1; CLEAR_FLAG(pd, PD_FLAG_PKT_HAS_MARK); } break; } if (cur_byte != OSDP_PKT_MARK) { pd->packet_scan_skip++; } prev_byte = cur_byte; } /* Found start of a new packet; wait until we have atleast the header */ len = osdp_rb_pop_buf(&pd->rx_rb, buf + pd->packet_buf_len, sizeof(struct osdp_packet_header) - 1); pd->packet_buf_len += len; if (pd->packet_buf_len < sizeof(struct osdp_packet_header)) { LOG_ERR("wrong packet data now."); return OSDP_ERR_PKT_WAIT; } pkt = (struct osdp_packet_header *)(buf + packet_has_mark(pd)); /* validate packet header */ if (pkt->som != OSDP_PKT_SOM) { LOG_ERR("Invalid SOM 0x%02x", pkt->som); return OSDP_ERR_PKT_FMT; } /* validate packet */ pkt_len = (pkt->len_msb << 8) | pkt->len_lsb; if (pkt_len > OSDP_PACKET_BUF_SIZE || pkt_len < sizeof(struct osdp_packet_header) + 1 || (is_cp_mode(pd) && !(pkt->pd_address & 0x80))) { /* * Since SoM byte was encountered and the packet structure is * invalid, we cannot just discard all bytes extracted so far * as there may another valid SoM in the subsequent stream. So * we need to re-scan rest of the extracted bytes for another * SoM before we can discard the extracted bytes. */ if(ISSET_FLAG(pd, PD_FLAG_PRINT_MASSAGE)) { LOG_ERR("packet_buf_len:%d, packet_Buf:", pd->packet_buf_len); print_hex(pd->packet_buf, pd->packet_buf_len); } if (phy_rescan_packet_buf(pd)) { LOG_DBG("Found nested SoM in re-scan; re-parsing"); } return OSDP_ERR_PKT_WAIT; } return pkt_len + packet_has_mark(pd); } static int phy_check_packet(struct osdp_pd *pd, uint8_t *buf, int pkt_len) { int pd_addr; uint16_t comp, cur; struct osdp_packet_header *pkt; if (packet_has_mark(pd)) { buf += 1; pkt_len -= 1; } pkt = (struct osdp_packet_header *)buf; /* validate CRC/checksum */ if (pkt->control & PKT_CONTROL_CRC) { pkt_len -= 2; /* consume CRC */ cur = (buf[pkt_len + 1] << 8) | buf[pkt_len]; comp = osdp_compute_crc16(buf, pkt_len); if (comp != cur) { LOG_ERR("Invalid crc 0x%04x/0x%04x", comp, cur); return OSDP_ERR_PKT_FMT; } } else { pkt_len -= 1; /* consume checksum */ cur = buf[pkt_len]; comp = osdp_compute_checksum(buf, pkt_len); if (comp != cur) { LOG_ERR("Invalid checksum %02x/%02x", comp, cur); return OSDP_ERR_PKT_FMT; } } /* validate PD address */ if(is_pd_mode(pd) && pkt->pd_address & 0x80) { if(ISSET_FLAG(pd, PD_FLAG_PRINT_MASSAGE)) { LOG_ERR("anther pd reply message, ignore it."); } return OSDP_ERR_PKT_SKIP; } pd_addr = pkt->pd_address & 0x7F; if (pd_addr != pd->address && pd_addr != 0x7F) { /* not addressed to us and was not broadcasted */ if (is_cp_mode(pd)) { LOG_ERR("Invalid pd address %d", pd_addr); return OSDP_ERR_PKT_CHECK; } return OSDP_ERR_PKT_SKIP; } /* validate sequence number */ comp = pkt->control & PKT_CONTROL_SQN; if (is_pd_mode(pd)) { if (comp == 0) { /** * CP is trying to restart communication by sending a 0. * The current PD implementation does not hold any state * between commands so we can just set seq_number to -1 * (so it gets incremented to 0 with a call to * phy_get_seq_number()) and invalidate any established * secure channels. */ pd->seq_number = -1; sc_deactivate(pd); } else if (comp == pd->seq_number) { /** * Sometimes, a CP re-sends the same command without * incrementing the sequence number. To handle such cases, * we will move the sequence back one step (with do_inc * set to -1) and then process the packet all over again * as if it was the first time we are seeing it. */ pd->seq_number -= 1; LOG_INF("Received a sequence repeat packet!"); } /** * For packets addressed to the broadcast address, the reply * must have address set to 0x7F and not the current PD's * address. To handle this case, let's capture this state in PD * flags. */ if (pd_addr == 0x7F) { SET_FLAG(pd, PD_FLAG_PKT_BROADCAST); } } else { if (comp == 0) { /** * Check for receiving a busy reply from the PD which would * have a sequence number of 0, come in an unsecured packet * of minimum length, and have the reply ID REPLY_BUSY. */ if ((pkt_len == 6) && (pkt->data[0] == REPLY_BUSY)) { pd->seq_number -= 1; LOG_INF("packet busy now."); return OSDP_ERR_PKT_BUSY; } } } cur = osdp_phy_get_seq_number(pd, is_pd_mode(pd)); if (cur != comp && !ISSET_FLAG(pd, PD_FLAG_SKIP_SEQ_CHECK)) { LOG_ERR("Packet sequence mismatch (%d/%d)", cur, comp); pd->reply_id = REPLY_NAK; pd->ephemeral_data[0] = OSDP_PD_NAK_SEQ_NUM; return OSDP_ERR_PKT_NACK; } return OSDP_ERR_PKT_NONE; } int osdp_phy_check_packet(struct osdp_pd *pd) { int ret = OSDP_ERR_PKT_FMT; ret = osdp_channel_receive(pd); /* always pull new bytes first */ /** * PD mode does not maintain state. When we receive the anything * from CP, we need to capture the timestamp so we can timeout and * clear the buffer on errors and stray RX data. */ if (is_pd_mode(pd) && pd->packet_buf_len == 0 && ret > 0) { pd->tstamp = osdp_millis_now(); if(ISSET_FLAG(pd, PD_FLAG_PRINT_MASSAGE)) { LOG_ERR("time stamp now:%lld", pd->tstamp); } } if (pd->packet_len == 0) { ret = phy_check_header(pd); if (ret < 0) { return ret; } pd->packet_len = ret; if (pd->packet_scan_skip) { LOG_DBG("Packet scan skipped:%u mark:%d", pd->packet_scan_skip, ISSET_FLAG(pd, PD_FLAG_PKT_HAS_MARK)); pd->packet_scan_skip = 0; } } /* We have a valid header, collect one full packet */ ret = osdp_rb_pop_buf(&pd->rx_rb, pd->packet_buf + pd->packet_buf_len, pd->packet_len - pd->packet_buf_len); pd->packet_buf_len += ret; if (pd->packet_buf_len != pd->packet_len) { return OSDP_ERR_PKT_WAIT; } if (is_packet_trace_enabled(pd)) { osdp_capture_packet(pd, pd->packet_buf, pd->packet_buf_len); } return phy_check_packet(pd, pd->packet_buf, pd->packet_len); } int osdp_phy_decode_packet(struct osdp_pd *pd, uint8_t **pkt_start) { uint8_t *data, *mac, *buf = pd->packet_buf; int mac_offset, is_cmd, len = pd->packet_buf_len; struct osdp_packet_header *pkt; bool is_sc_active = sc_is_active(pd); if (packet_has_mark(pd)) { buf += 1; len -= 1; } pkt = (struct osdp_packet_header *)buf; len -= pkt->control & PKT_CONTROL_CRC ? 2 : 1; mac_offset = len - 4; data = pkt->data; len -= sizeof(struct osdp_packet_header); if (pkt->control & PKT_CONTROL_SCB) { if (is_pd_mode(pd) && !sc_is_capable(pd)) { LOG_ERR("PD is not SC capable"); pd->reply_id = REPLY_NAK; pd->ephemeral_data[0] = OSDP_PD_NAK_SC_UNSUP; return OSDP_ERR_PKT_NACK; } if (pkt->data[1] < SCS_11 || pkt->data[1] > SCS_18) { LOG_ERR("Invalid SB Type"); pd->reply_id = REPLY_NAK; pd->ephemeral_data[0] = OSDP_PD_NAK_SC_COND; return OSDP_ERR_PKT_NACK; } if (!is_sc_active && pkt->data[1] > SCS_14) { LOG_ERR("Invalid SCS type (%x)", pkt->data[1]); pd->reply_id = REPLY_NAK; pd->ephemeral_data[0] = OSDP_PD_NAK_SC_COND; return OSDP_ERR_PKT_NACK; } if (pkt->data[1] == SCS_11 || pkt->data[1] == SCS_13) { /** * CP signals PD to use SCBKD by setting SCB data byte * to 0. But since SCBK-D is insecure access, it's * usage is limited to install mode (a provisioning time * mode) only. */ if (ISSET_FLAG(pd, OSDP_FLAG_INSTALL_MODE) && pkt->data[2] == 0) { SET_FLAG(pd, PD_FLAG_SC_USE_SCBKD); } } data = pkt->data + pkt->data[0]; len -= pkt->data[0]; /* consume security block */ } else { if (is_cp_mode(pd)) { /** * If the current packet is an ACK for a KEYSET, the PD * might have discarded the secure channel session keys * in favour of the new key we sent and hence this packet * may reach us in plain text. To work with such PDs, we * must also discard our secure session. * * For now, let's just pretend that SC is deactivated so * the rest of this method finishes normally. The actual * secure channel is actually discarded from the CP * state machine. */ if (pd->cmd_id == CMD_KEYSET && pkt->data[0] == REPLY_ACK) { is_sc_active = false; } /** * When the PD discards it's secure channel for some * reason, it responds with NACK(6) in plaintext. There * may be other cases too. So we will allow NAKs in */ if (is_sc_active && pkt->data[0] == REPLY_NAK) { is_sc_active = false; } } if (is_sc_active) { LOG_ERR("Received plain-text message in SC"); pd->reply_id = REPLY_NAK; pd->ephemeral_data[0] = OSDP_PD_NAK_SC_COND; return OSDP_ERR_PKT_NACK; } } if (is_sc_active && pkt->control & PKT_CONTROL_SCB && pkt->data[1] >= SCS_15) { /* validate MAC */ is_cmd = is_pd_mode(pd); osdp_compute_mac(pd, is_cmd, buf, mac_offset); mac = is_cmd ? pd->sc.c_mac : pd->sc.r_mac; if (memcmp(buf + mac_offset, mac, 4) != 0) { LOG_ERR("Invalid MAC; discarding SC"); sc_deactivate(pd); pd->reply_id = REPLY_NAK; pd->ephemeral_data[0] = OSDP_PD_NAK_SC_COND; return OSDP_ERR_PKT_NACK; } len -= 4; /* consume MAC */ /* decrypt data block */ if (pkt->data[1] == SCS_17 || pkt->data[1] == SCS_18) { /** * Only the data portion of message (after id byte) * is encrypted. While (en)decrypting, we must skip * header (6), security block (2) and cmd/reply id (1) * bytes if cmd/reply has no data, use SCS_15/SCS_16. * * At this point, the header and security block is * already consumed. So we can just skip the cmd/reply * ID (data[0]) when calling osdp_decrypt_data(). */ len = osdp_decrypt_data(pd, is_cmd, data + 1, len - 1); if (len < 0) { LOG_ERR("Failed at decrypt; discarding SC"); sc_deactivate(pd); pd->reply_id = REPLY_NAK; pd->ephemeral_data[0] = OSDP_PD_NAK_SC_COND; return OSDP_ERR_PKT_NACK; } if (len == 0) { /** * If cmd/reply has no data, PD "should" have * used SCS_15/SCS_16 but we will be tolerant * towards those faulty implementations. */ LOG_WRN_ONCE("Received encrypted data block with 0 " "length; tolerating non-conformance!"); } len += 1; /* put back cmd/reply ID */ } } if (is_data_trace_enabled(pd)) { int ret = len; /** * Here, we move the decrypted data block right after the * header so we can pass the entire packet to the tracing * infrastructure allowing us to reuse the same protocol * dissector for regular packet trace as well as data trace * files. * * We also touch up the packet so that it can be parsed/decoded * correctly. Since none of the later states require the * header, we are free to mangle it as needed for our * convenience. * * The following changes performed: * - Update the length field with the modifications * - Remove `PKT_CONTROL_SCB` bit to show no sign of a secure * channels' existence. * - Set a new bit `PKT_TRACE_MANGLED` so the dissector can * skip the PacketCheck bytes (maybe other housekeeping?). */ memmove(pkt->data, data, len); *pkt_start = pkt->data; len += sizeof(struct osdp_packet_header); pkt->control &= ~PKT_CONTROL_SCB; pkt->control |= PKT_TRACE_MANGLED; pkt->len_lsb = BYTE_0(len); pkt->len_msb = BYTE_1(len); osdp_capture_packet(pd, (uint8_t *)pkt, len); return ret; } *pkt_start = data; return len; } void osdp_phy_state_reset(struct osdp_pd *pd, bool is_error) { pd->packet_buf_len = 0; pd->packet_len = 0; pd->phy_state = 0; if (is_error) { pd->phy_retry_count = 0; pd->seq_number = -1; if (pd->channel.flush) { pd->channel.flush(pd->channel.data); } } } #ifdef UNIT_TESTING int (*test_osdp_phy_packet_finalize)(struct osdp_pd *pd, uint8_t *buf, int len, int max_len) = osdp_phy_packet_finalize; #endif
09-27
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值