struct octet_buffer read32 (int fd, enum DATA_ZONE zone, uint8_t addr) { uint8_t param2[2] = {0}; uint8_t param1 = set_zone_bits (zone); uint8_t READ_32_MASK = 0b10000000; param1 |= READ_32_MASK; param2[0] = addr; struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_READ); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, NULL, 0); set_execution_time (&c, 0, READ_AVG_EXEC); const unsigned int LENGTH_OF_RESPONSE = 32; struct octet_buffer buf = make_buffer (LENGTH_OF_RESPONSE); if (RSP_SUCCESS != process_command (fd, &c, buf.ptr, LENGTH_OF_RESPONSE)) { free_wipe (buf.ptr, LENGTH_OF_RESPONSE); buf.ptr = NULL; buf.len = 0; } return buf; }
static struct wipe_desc * do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int quiet, int force) { int flags; blkid_probe pr; struct wipe_desc *w, *wp0 = clone_offset(wp); int zap = all ? 1 : wp->zap; flags = O_RDWR; if (!force) flags |= O_EXCL; pr = new_probe(devname, flags); if (!pr) return NULL; while (blkid_do_probe(pr) == 0) { wp = get_desc_for_probe(wp, pr); if (!wp) break; /* Check if offset is in provided list */ w = wp0; while(w && w->offset != wp->offset) w = w->next; if (wp0 && !w) continue; /* Mark done if found in provided list */ if (w) w->on_disk = wp->on_disk; if (!wp->on_disk) continue; if (zap) do_wipe_real(pr, devname, wp, noact, quiet); } for (w = wp0; w != NULL; w = w->next) { if (!w->on_disk && !quiet) warnx(_("%s: offset 0x%jx not found"), devname, w->offset); } fsync(blkid_probe_get_fd(pr)); close(blkid_probe_get_fd(pr)); blkid_free_probe(pr); free_wipe(wp0); return wp; }
bool record_keys (struct key_container *keys) { assert (NULL != keys); bool result = false; FILE *f = NULL; struct passwd *pw = getpwuid (getuid ()); assert (NULL != pw); const char *home = pw->pw_dir; unsigned int filename_len = strlen (home) + strlen (KEY_STORE) + 1; char *filename = (char *)malloc_wipe (filename_len); strcpy (filename, home); strcat (filename, KEY_STORE); if ((f = fopen (filename, "w")) != NULL) { fprintf (f, "# Hashlet key store written from version: %s\n", PACKAGE_VERSION); unsigned int x = 0; for (x=0; x< get_max_keys (); x++) { fprintf (f, "key_slot_%02u ",x); unsigned int y = 0; for (y=0; y < keys->keys[x].len; y++) { fprintf (f, "%02X", keys->keys[x].ptr[y]); } fprintf (f, "%s", "\n"); } fclose (f); result = true; } else { CTX_LOG (INFO, "Failed to open %s", filename); perror ("Error"); } free_wipe ((uint8_t *)filename, filename_len); return result; }
uint16_t crc_data_otp_zone (struct octet_buffer data, struct octet_buffer otp) { const unsigned int len = otp.len + data.len; uint8_t *buf = malloc_wipe (len); memcpy (buf, data.ptr, data.len); memcpy (buf + data.len, otp.ptr, otp.len); uint16_t crc = calculate_crc16 (buf, len); free_wipe (buf, len); return crc; }
int main(int argc, char **argv) { struct wipe_desc *wp = NULL; int c, all = 0, has_offset = 0, noact = 0, mode = 0; const char *fname; struct option longopts[] = { { "all", 0, 0, 'a' }, { "help", 0, 0, 'h' }, { "no-act", 0, 0, 'n' }, { "offset", 1, 0, 'o' }, { "parsable", 0, 0, 'p' }, { NULL, 0, 0, 0 } }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt_long(argc, argv, "ahno:p", longopts, NULL)) != -1) { switch(c) { case 'a': all++; break; case 'h': usage(stdout); break; case 'n': noact++; break; case 'o': wp = add_offset(wp, strtoll_offset(optarg), 1); has_offset++; break; case 'p': mode = WP_MODE_PARSABLE; break; default: usage(stderr); break; } } if (wp && all) errx(EXIT_FAILURE, _("--offset and --all are mutually exclusive")); if (optind == argc) usage(stderr); fname = argv[optind++]; wp = read_offsets(wp, fname, all); if (wp) { if (has_offset || all) do_wipe(wp, fname, noact); else print_all(wp, mode); free_wipe(wp); } return EXIT_SUCCESS; }
int main(int argc, char **argv) { struct wipe_desc *wp0 = NULL, *wp; int c, all = 0, has_offset = 0, noact = 0, quiet = 0; int mode = WP_MODE_PRETTY; static const struct option longopts[] = { { "all", 0, 0, 'a' }, { "help", 0, 0, 'h' }, { "no-act", 0, 0, 'n' }, { "offset", 1, 0, 'o' }, { "parsable", 0, 0, 'p' }, { "quiet", 0, 0, 'q' }, { "types", 1, 0, 't' }, { "version", 0, 0, 'V' }, { NULL, 0, 0, 0 } }; static const ul_excl_t excl[] = { /* rows and cols in in ASCII order */ { 'a','o' }, { 0 } }; int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((c = getopt_long(argc, argv, "ahno:pqt:V", longopts, NULL)) != -1) { err_exclusive_options(c, longopts, excl, excl_st); switch(c) { case 'a': all++; break; case 'h': usage(stdout); break; case 'n': noact++; break; case 'o': wp0 = add_offset(wp0, strtosize_or_err(optarg, _("invalid offset argument")), 1); has_offset++; break; case 'p': mode = WP_MODE_PARSABLE; break; case 'q': quiet++; break; case 't': type_pattern = optarg; break; case 'V': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); return EXIT_SUCCESS; default: usage(stderr); break; } } if (optind == argc) usage(stderr); if (!all && !has_offset) { /* * Print only */ while (optind < argc) { wp0 = read_offsets(NULL, argv[optind++]); if (wp0) print_all(wp0, mode); free_wipe(wp0); } } else { /* * Erase */ while (optind < argc) { wp = clone_offset(wp0); wp = do_wipe(wp, argv[optind++], noact, all, quiet); free_wipe(wp); } } return EXIT_SUCCESS; }
int main(int argc, char **argv) { struct wipe_desc *wp0 = NULL, *wp; int c, has_offset = 0, flags = 0; int mode = WP_MODE_PRETTY; static const struct option longopts[] = { { "all", 0, 0, 'a' }, { "backup", 0, 0, 'b' }, { "force", 0, 0, 'f' }, { "help", 0, 0, 'h' }, { "no-act", 0, 0, 'n' }, { "offset", 1, 0, 'o' }, { "parsable", 0, 0, 'p' }, { "quiet", 0, 0, 'q' }, { "types", 1, 0, 't' }, { "version", 0, 0, 'V' }, { NULL, 0, 0, 0 } }; static const ul_excl_t excl[] = { /* rows and cols in in ASCII order */ { 'a','o' }, { 0 } }; int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((c = getopt_long(argc, argv, "afhno:pqt:V", longopts, NULL)) != -1) { err_exclusive_options(c, longopts, excl, excl_st); switch(c) { case 'a': flags |= WP_FL_ALL; break; case 'b': flags |= WP_FL_BACKUP; break; case 'f': flags |= WP_FL_FORCE; break; case 'h': usage(stdout); break; case 'n': flags |= WP_FL_NOACT; break; case 'o': wp0 = add_offset(wp0, strtosize_or_err(optarg, _("invalid offset argument")), 1); has_offset++; break; case 'p': mode = WP_MODE_PARSABLE; break; case 'q': flags |= WP_FL_QUIET; break; case 't': type_pattern = optarg; break; case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; default: usage(stderr); break; } } if (optind == argc) usage(stderr); if ((flags & WP_FL_BACKUP) && !((flags & WP_FL_ALL) || has_offset)) warnx(_("The --backup option is meaningless in this context")); if (!(flags & WP_FL_ALL) && !has_offset) { /* * Print only */ while (optind < argc) { wp0 = read_offsets(NULL, argv[optind++]); if (wp0) print_all(wp0, mode); free_wipe(wp0); } } else { /* * Erase */ while (optind < argc) { wp = clone_offset(wp0); wp = do_wipe(wp, argv[optind++], flags); free_wipe(wp); } } return EXIT_SUCCESS; }
static struct wipe_desc * do_wipe(struct wipe_desc *wp, const char *devname, int flags) { int mode = O_RDWR, reread = 0; blkid_probe pr; struct wipe_desc *w, *wp0; int zap = (flags & WP_FL_ALL) ? 1 : wp->zap; char *backup = NULL; if (!(flags & WP_FL_FORCE)) mode |= O_EXCL; pr = new_probe(devname, mode); if (!pr) return NULL; if (zap && (flags & WP_FL_BACKUP)) { const char *home = getenv ("HOME"); if (!home) errx(EXIT_FAILURE, _("failed to create a signature backup, $HOME undefined")); xasprintf (&backup, "%s/wipefs-%s-", home, basename(devname)); } wp0 = clone_offset(wp); while (blkid_do_probe(pr) == 0) { wp = get_desc_for_probe(wp, pr); if (!wp) break; /* Check if offset is in provided list */ w = wp0; while(w && w->offset != wp->offset) w = w->next; if (wp0 && !w) continue; /* Mark done if found in provided list */ if (w) w->on_disk = wp->on_disk; if (!wp->on_disk) continue; if (zap) { if (backup) do_backup(wp, backup); do_wipe_real(pr, devname, wp, flags); if (wp->is_parttable) reread = 1; } } for (w = wp0; w != NULL; w = w->next) { if (!w->on_disk && !(flags & WP_FL_QUIET)) warnx(_("%s: offset 0x%jx not found"), devname, w->offset); } fsync(blkid_probe_get_fd(pr)); if (reread) rereadpt(blkid_probe_get_fd(pr), devname); close(blkid_probe_get_fd(pr)); blkid_free_probe(pr); free_wipe(wp0); free(backup); return wp; }
static struct wipe_desc * do_wipe(struct wipe_desc *wp, const char *devname, int flags) { int mode = O_RDWR, reread = 0, need_force = 0; blkid_probe pr; struct wipe_desc *w, *wp0; int zap = (flags & WP_FL_ALL) ? 1 : wp->zap; char *backup = NULL; if (!(flags & WP_FL_FORCE)) mode |= O_EXCL; pr = new_probe(devname, mode); if (!pr) return NULL; if (zap && (flags & WP_FL_BACKUP)) { const char *home = getenv ("HOME"); char *tmp = xstrdup(devname); if (!home) errx(EXIT_FAILURE, _("failed to create a signature backup, $HOME undefined")); xasprintf (&backup, "%s/wipefs-%s-", home, basename(tmp)); free(tmp); } wp0 = clone_offset(wp); while (blkid_do_probe(pr) == 0) { wp = get_desc_for_probe(wp, pr); if (!wp) break; /* Check if offset is in provided list */ w = wp0; while(w && w->offset != wp->offset) w = w->next; if (wp0 && !w) continue; /* Mark done if found in provided list */ if (w) w->on_disk = wp->on_disk; if (!wp->on_disk) continue; if (!(flags & WP_FL_FORCE) && wp->is_parttable && !blkid_probe_is_wholedisk(pr)) { warnx(_("%s: ignoring nested \"%s\" partition table " "on non-whole disk device"), devname, wp->type); need_force = 1; continue; } if (zap) { if (backup) do_backup(wp, backup); do_wipe_real(pr, devname, wp, flags); if (wp->is_parttable) reread = 1; } } for (w = wp0; w != NULL; w = w->next) { if (!w->on_disk && !(flags & WP_FL_QUIET)) warnx(_("%s: offset 0x%jx not found"), devname, (uintmax_t)w->offset); } if (need_force) warnx(_("Use the --force option to force erase.")); fsync(blkid_probe_get_fd(pr)); #ifdef BLKRRPART if (reread && (mode & O_EXCL)) rereadpt(blkid_probe_get_fd(pr), devname); #endif close(blkid_probe_get_fd(pr)); blkid_free_probe(pr); free_wipe(wp0); free(backup); return wp; }
enum STATUS_RESPONSE read_and_validate (int fd, uint8_t *buf, unsigned int len) { uint8_t* tmp = NULL; const int PAYLOAD_LEN_SIZE = 1; const int CRC_SIZE = 2; enum STATUS_RESPONSE status = RSP_COMM_ERROR; unsigned int recv_buf_len = 0; bool crc_valid; unsigned int crc_offset; int read_bytes; const unsigned int STATUS_RSP = 4; assert (NULL != buf); recv_buf_len = len + PAYLOAD_LEN_SIZE + CRC_SIZE; crc_offset = recv_buf_len - 2; /* The buffer that comes back has a length byte at the front and a * two byte crc at the end. */ tmp = malloc_wipe (recv_buf_len); read_bytes = i2c_read (fd, tmp, recv_buf_len); /* First Case: We've read the buffer and it's a status packet */ if (read_bytes == recv_buf_len && tmp[0] == STATUS_RSP) { print_hex_string ("Status RSP", tmp, tmp[0]); status = get_status_response (tmp); CTX_LOG (DEBUG, status_to_string (status)); } /* Second case: We received the expected message length */ else if (read_bytes == recv_buf_len && tmp[0] == recv_buf_len) { print_hex_string ("Received RSP", tmp, recv_buf_len); crc_valid = is_crc_16_valid (tmp, tmp[0] - CRC_16_LEN, tmp + crc_offset); if (true == crc_valid) { wipe (buf, len); memcpy (buf, &tmp[1], len); status = RSP_SUCCESS; } else { perror ("CRC FAIL!\n"); } } else { CTX_LOG (DEBUG,"Read failed, retrying"); status = RSP_NAK; } free_wipe (tmp, recv_buf_len); return status; }