15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
0
|
// rc2.c, version 0.2.0 |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
1
|
// OMKOV cryptutils rc2 |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
2
|
// Copyright (C) 2021, Jakob Wakeling |
45f70e3 |
Jamozed |
2022-03-06 17:15:30 |
3
|
// MIT Licence |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
4
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
5
|
#include "util/error.c" |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
6
|
#include "util/optget.h" |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
7
|
#include "util/rc2.h" |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
8
|
#include "util/util.h" |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
9
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
10
|
#include <limits.h> |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
11
|
#include <stdio.h> |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
12
|
#include <string.h> |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
13
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
14
|
#define VERSION "0.2.0" |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
15
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
16
|
static struct lop lops[] = { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
17
|
{ "help", ARG_NUL, 256 }, |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
18
|
{ "version", ARG_NUL, 257 }, |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
19
|
{ NULL, 0, 0 } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
20
|
}; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
21
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
22
|
static int mode = 0; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
23
|
static char *karg; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
24
|
static int larg; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
25
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
26
|
static inline void rc2(const char *ifile, const char *ofile); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
27
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
28
|
static void hlp(void); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
29
|
static void ver(void); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
30
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
31
|
int main(int ac, char *av[]) { A0 = av[0]; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
32
|
struct opt opt = OPTGET_INIT; opt.str = "dek:l:m"; opt.lops = lops; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
33
|
for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
34
|
case 'e': { mode = 0; } break; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
35
|
case 'd': { mode = 1; } break; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
36
|
case 'k': { karg = opt.arg; } break; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
37
|
case 'l': { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
38
|
register int d; register char *p = opt.arg; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
39
|
for (larg = 0; *p >= '0' && *p < '9'; ++p) { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
40
|
d = (int)*p - '0'; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
41
|
if (larg > (INT_MAX - d) / 10) { break; } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
42
|
larg = larg * 10 + d; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
43
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
44
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
45
|
if (*p) { error(1, "invalid length"); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
46
|
if (larg > 1024) { error(1, "length must be at most 1024"); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
47
|
if (larg == 0) { error(1, "length must be greater than 0"); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
48
|
} break; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
49
|
case 'm': { /* TODO */ error(1, "-m not implemented"); } break; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
50
|
case 256: { hlp(); } return 0; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
51
|
case 257: { ver(); } return 0; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
52
|
default: {} return 1; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
53
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
54
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
55
|
if (!larg) { larg = 1024; } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
56
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
57
|
if (opt.ind == ac) { error(1, "missing operand"); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
58
|
else if (opt.ind == ac - 1) { rc2(av[opt.ind], NULL); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
59
|
else if (opt.ind == ac - 2) { rc2(av[opt.ind], av[opt.ind + 1]); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
60
|
else { error(1, "excess operand"); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
61
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
62
|
return 0; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
63
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
64
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
65
|
static inline void rc2(const char *ifile, const char *ofile) { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
66
|
struct rc2 ctx; u8 b1[128], b2[16]; FILE *fk, *fi, *fo; size_t kl, fl; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
67
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
68
|
if (!karg) { error(1, "-k is required"); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
69
|
else if (!(fk = fopen(karg, "r"))) { error(1, "%s: %s", karg, serr()); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
70
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
71
|
// TODO Check key size is within bounds |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
72
|
kl = fread(b1, 1, sizeof (b1), fk); fclose(fk); fk = NULL; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
73
|
rc2expand(&ctx, b1, kl, larg); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
74
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
75
|
if (!ifile) { fi = stdin; } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
76
|
else if (!(fi = fopen(ifile, "r"))) { error(1, "%s: %s", ifile, serr()); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
77
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
78
|
if (!ofile) { fo = stdout; } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
79
|
else if (!(fo = fopen(ofile, "w"))) { error(1, "%s: %s", ofile, serr()); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
80
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
81
|
for (size_t c; (c = fread(b1, 1, 8, fi));) { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
82
|
while (c >= 8) { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
83
|
memset(b2, 0, 8); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
84
|
if (mode == 0) { rc2encrypt(&ctx, b1, b2); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
85
|
if (mode == 1) { rc2decrypt(&ctx, b1, b2); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
86
|
fwrite(b2, 1, 8, fo); c -= 8; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
87
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
88
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
89
|
if (c != 0) { // Should only be true during encryption |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
90
|
memset(b2, 0, 8); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
91
|
if (mode == 0) { rc2encrypt(&ctx, b1, b2); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
92
|
fwrite(b2, 1, 8, fo); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
93
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
94
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
95
|
memset(b1, 0, 8); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
96
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
97
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
98
|
if (fi != stdin) { fclose(fi); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
99
|
if (fo != stdin) { fclose(fo); } |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
100
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
101
|
return; |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
102
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
103
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
104
|
/* Print help information. */ |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
105
|
static void hlp(void) { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
106
|
puts("rc2 - encrypt and decrypt files using rc2\n"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
107
|
puts("usage: rc2 [-d|-e] [-k keyfile] [-l length] [-m mode] [infile] " |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
108
|
"[outfile]\n"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
109
|
puts("options:"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
110
|
puts(" -d Decrypt the input data"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
111
|
puts(" -e Encrypt the input data (default)"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
112
|
puts(" -k file Specify keyfile"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
113
|
puts(" -l length Override effective key length"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
114
|
puts(" -m mode Specify block cipher mode of operation"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
115
|
puts(" --help Display help information"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
116
|
puts(" --version Display version information"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
117
|
} |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
118
|
|
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
119
|
/* Print version information. */ |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
120
|
static void ver(void) { |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
121
|
puts("OMKOV cryptutils rc2, version " VERSION); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
122
|
puts("Copyright (C) 2021, Jakob Wakeling"); |
45f70e3 |
Jamozed |
2022-03-06 17:15:30 |
123
|
puts("MIT Licence (https://opensource.org/licenses/MIT)"); |
15c1e58 |
Jamozed |
2022-02-05 19:40:12 |
124
|
} |
|
|
|
125
|
|