nec-enc.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * nec-enc.c - encode/decode nec firmware with key
  4. *
  5. * based on xorimage.c in libreCMC
  6. *
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <stdint.h>
  12. #include <unistd.h>
  13. #define KEY_LEN 16
  14. #define PATTERN_LEN 251
  15. static int
  16. xor_pattern(uint8_t *data, size_t len, const char *key, int k_len, int k_off)
  17. {
  18. int offset = k_off;
  19. while (len--) {
  20. *data ^= key[offset];
  21. data++;
  22. offset = (offset + 1) % k_len;
  23. }
  24. return offset;
  25. }
  26. static void xor_data(uint8_t *data, size_t len, const uint8_t *pattern)
  27. {
  28. for (int i = 0; i < len; i++) {
  29. *data ^= pattern[i];
  30. data++;
  31. }
  32. }
  33. static void __attribute__((noreturn)) usage(void)
  34. {
  35. fprintf(stderr, "Usage: nec-enc -i infile -o outfile -k <key>\n");
  36. exit(EXIT_FAILURE);
  37. }
  38. static unsigned char buf_pattern[4096], buf[4096];
  39. int main(int argc, char **argv)
  40. {
  41. int k_off = 0, ptn = 0, c, ret = EXIT_SUCCESS;
  42. char *ifn = NULL, *ofn = NULL, *key = NULL;
  43. size_t n, k_len;
  44. FILE *out, *in;
  45. while ((c = getopt(argc, argv, "i:o:k:h")) != -1) {
  46. switch (c) {
  47. case 'i':
  48. ifn = optarg;
  49. break;
  50. case 'o':
  51. ofn = optarg;
  52. break;
  53. case 'k':
  54. key = optarg;
  55. break;
  56. case 'h':
  57. default:
  58. usage();
  59. }
  60. }
  61. if (optind != argc || optind == 1) {
  62. fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]);
  63. usage();
  64. }
  65. in = fopen(ifn, "r");
  66. if (!in) {
  67. perror("can not open input file");
  68. usage();
  69. }
  70. out = fopen(ofn, "w");
  71. if (!out) {
  72. perror("can not open output file");
  73. usage();
  74. }
  75. if (!key) {
  76. fprintf(stderr, "key is not specified\n");
  77. usage();
  78. }
  79. k_len = strnlen(key, KEY_LEN + 1);
  80. if (k_len == 0 || k_len > KEY_LEN) {
  81. fprintf(stderr, "key length is not in range (0,%d)\n", KEY_LEN);
  82. usage();
  83. }
  84. while ((n = fread(buf, 1, sizeof(buf), in)) > 0) {
  85. for (int i = 0; i < n; i++) {
  86. buf_pattern[i] = ptn + 1;
  87. ptn++;
  88. if (ptn > 250)
  89. ptn = 0;
  90. }
  91. k_off = xor_pattern(buf_pattern, n, key, k_len, k_off);
  92. xor_data(buf, n, buf_pattern);
  93. if (fwrite(buf, 1, n, out) != n) {
  94. perror("failed to write");
  95. ret = EXIT_FAILURE;
  96. goto out;
  97. }
  98. }
  99. if (ferror(in)) {
  100. perror("failed to read");
  101. ret = EXIT_FAILURE;
  102. goto out;
  103. }
  104. out:
  105. fclose(in);
  106. fclose(out);
  107. return ret;
  108. }