int main(int argc, char **argv) { if (argc < 2) { help(argv[0]); return 1; } atsha_set_verbose(); atsha_set_log_callback(log_callback); int status; struct atsha_handle *handle; handle = atsha_open(); if (handle == NULL) { fprintf(stderr, "Device couldn't be opened.\n"); return 3; } if (strcmp(argv[1], CMD_SN) == 0) { atsha_big_int sn; status = atsha_serial_number(handle, &sn); if (status != ATSHA_ERR_OK) { fprintf(stderr, "Serial number error: %s\n", atsha_error_name(status)); atsha_close(handle); return 3; } print_number(sn.bytes, sn.data); } else if (strcmp(argv[1], CMD_HWREV) == 0) { atsha_big_int sn; status = atsha_serial_number(handle, &sn); if (status != ATSHA_ERR_OK) { fprintf(stderr, "HW revision number error: %s\n", atsha_error_name(status)); atsha_close(handle); return 3; } /* Serial number has 8bytes 4bytes of HW revision number and 4bytes unique number. So... use only first 4 bytes. */ print_number(4, sn.data); } else if (strcmp(argv[1], CMD_RND) == 0) { atsha_big_int sn; status = atsha_random(handle, &sn); if (status != ATSHA_ERR_OK) { fprintf(stderr, "Random numer generation error: %s\n", atsha_error_name(status)); atsha_close(handle); return 3; } for(int i = 0; i < sn.bytes; i++) { putchar(sn.data[i]); } } else if (strcmp(argv[1], CMD_HMAC) == 0) { char buff[BUFFSIZE]; atsha_big_int challenge; atsha_big_int response; if (!read_challenge(buff)) { fprintf(stderr, "Input couldn't be read.\n"); atsha_close(handle); return 2; } if (!get_challenge_from_input(buff, &challenge)) { fprintf(stderr, "Input couldn't be converted.\n"); atsha_close(handle); return 2; } status = atsha_challenge_response(handle, challenge, &response); if (status != ATSHA_ERR_OK) { fprintf(stderr, "Challenge response error: %s\n", atsha_error_name(status)); atsha_close(handle); return 3; } print_number(response.bytes, response.data); } else if (strcmp(argv[1], CMD_FILEHMAC) == 0) { atsha_big_int challenge; atsha_big_int response; if (!get_file_sha256(&challenge, stdin)) { fprintf(stderr, "Input couldn't be read.\n"); atsha_close(handle); return 2; } status = atsha_challenge_response(handle, challenge, &response); if (status != ATSHA_ERR_OK) { fprintf(stderr, "Challenge response error: %s\n", atsha_error_name(status)); atsha_close(handle); return 3; } print_number(response.bytes, response.data); } else if ((strcmp(argv[1], CMD_MAC) == 0) && (argc == 3)) { unsigned char n = atoi(argv[2]); if (n <= 0) { fprintf(stderr, "Bad MAC address count requested.\n"); return 1; } atsha_big_int prefix; atsha_big_int addr; status = atsha_raw_otp_read(handle, ATSHA204_OTP_MEMORY_MAP_MAC_PREFIX, &prefix); if (status != ATSHA_ERR_OK) { fprintf(stderr, ": Get MAC address prefix failed: %s\n", atsha_error_name(status)); atsha_close(handle); return 3; } status = atsha_raw_otp_read(handle, ATSHA204_OTP_MEMORY_MAP_MAC_ADDR, &addr); if (status != ATSHA_ERR_OK) { fprintf(stderr, "Get MAC address suffix failed: %s\n", atsha_error_name(status)); atsha_close(handle); return 3; } assert(sizeof(unsigned int) >= 4); unsigned int mac_as_number = 0, mac_as_number_orig = 0; unsigned char tmp_mac[6]; memcpy(tmp_mac, (prefix.data+1), 3); mac_as_number_orig |= (addr.data[1] << 8*2); mac_as_number_orig |= (addr.data[2] << 8*1); mac_as_number_orig |= addr.data[3]; if (mac_as_number_orig > (((unsigned int)0xFFFFFF)-n)) { fprintf(stderr, "MAC address count is to big!\n"); return 4; } for (char i = 0; i < n; i++) { mac_as_number = mac_as_number_orig; mac_as_number_orig++; tmp_mac[5] = mac_as_number & 0xFF; mac_as_number >>= 8; tmp_mac[4] = mac_as_number & 0xFF; mac_as_number >>= 8; tmp_mac[3] = mac_as_number & 0xFF; mac_as_number >>= 8; printf("%02X:%02X:%02X:%02X:%02X:%02X\n", tmp_mac[0], tmp_mac[1], tmp_mac[2], tmp_mac[3], tmp_mac[4], tmp_mac[5]); } } else {
void interface_socket_callback(evutil_socket_t fd, short type, struct endpoint* endpoint) { struct rcontext rcontext; char ibuf[1500]; char obuf[1500]; char buf1[128], buf2[128]; ssize_t ilength, olength; struct master_config* config = endpoint->config; ilength = datagram_read(fd, ibuf, sizeof(ibuf), &rcontext.from); if (ilength < 0) { return; } if (udpaddress_equals(&endpoint->local, &rcontext.from)) { return; } rcontext.endpoint = endpoint; rcontext.rendpoint = rendpoint_find_by_address(config, &rcontext.from); rcontext.session = session_find_by_address(endpoint->config, &endpoint->local, &rcontext.from); rcontext.config = config; fprintf(stderr, "read %d bytes %s <=> %s. session: %d, rendpoint: %d\n", (int)ilength, udpaddress_string(&rcontext.from, buf1), udpaddress_string(&endpoint->local, buf2), rcontext.session != 0, rcontext.rendpoint != 0); olength = -1; if (rcontext.session) { if (rcontext.session->key1) { rcontext.rkey = rcontext.session->key1; olength = xdecrypt(config, rcontext.session->key1, ibuf, ilength, obuf); if (olength > 0) { fprintf(stderr, "!!key1\n"); } } if (olength < 0 && rcontext.session->key2) { rcontext.rkey = rcontext.session->key2; olength = xdecrypt(config, rcontext.session->key2, ibuf, ilength, obuf); if (olength > 0) { fprintf(stderr, "!!key2\n"); } } } if (olength < 0) { rcontext.rkey = config->key0; olength = xdecrypt(config, config->key0, ibuf, ilength, obuf); if (olength > 0) { fprintf(stderr, "!!key0\n"); } } if (olength < 0) { fprintf(stderr, "!!decrypt failed\n"); return; } if (proto_decode(&rcontext.proto, obuf, olength) <= 0) { fprintf(stderr, "!!decode failed\n"); return; } switch (rcontext.proto.type) { case PROTO_OFFER: fprintf(stderr, "!!Received offer\n"); // key change read_offer(&rcontext, &rcontext.proto); break; case PROTO_CHALLENGE: fprintf(stderr, "!!Received challenge\n"); read_challenge(&rcontext, &rcontext.proto); break; case PROTO_CONFIRM: // key change confirmed fprintf(stderr, "!!Received confirm\n"); read_confirm(&rcontext, &rcontext.proto); break; case PROTO_ACCEPTED: fprintf(stderr, "!!Received accepted\n"); read_accept(&rcontext, &rcontext.proto); break; case PROTO_DATA: fprintf(stderr, "!!Received data\n"); if (rcontext.session == 0) { break; } if (rcontext.rkey == config->key0) { break; } read_data(&rcontext, &rcontext.proto); break; default: assert(0); break; } }