1 /* SPDX-License-Identifier: GPL-2.0-or-later
2 * Copyright (C) 2023 Eneas Ulir de Queiroz
12 #if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */
13 static inline mbedtls_cipher_mode_t
mbedtls_cipher_info_get_mode(
14 const mbedtls_cipher_info_t
*info
)
17 return MBEDTLS_MODE_NONE
;
23 static inline size_t mbedtls_cipher_info_get_key_bitlen(
24 const mbedtls_cipher_info_t
*info
)
29 return info
->key_bitlen
;
33 static inline const char *mbedtls_cipher_info_get_name(
34 const mbedtls_cipher_info_t
*info
)
43 static inline size_t mbedtls_cipher_info_get_iv_size(
44 const mbedtls_cipher_info_t
*info
)
53 static inline size_t mbedtls_cipher_info_get_block_size(
54 const mbedtls_cipher_info_t
*info
)
60 return info
->block_size
;
64 unsigned char *hexstr2buf(const char *str
, long *len
)
67 long inlen
= strlen(str
);
75 for (long x
= 0; x
< *len
; x
++)
76 sscanf(str
+ x
* 2, "%2hhx", buf
+ x
);
80 const cipher_t
*get_default_cipher(void)
82 return mbedtls_cipher_info_from_type (MBEDTLS_CIPHER_AES_128_CBC
);
85 static char* upperstr(char *str
) {
86 for (char *s
= str
; *s
; s
++)
87 *s
= toupper((unsigned char) *s
);
91 const cipher_t
*get_cipher_or_print_error(char *name
)
93 const mbedtls_cipher_info_t
*cipher
;
95 cipher
= mbedtls_cipher_info_from_string(upperstr(name
));
99 fprintf(stderr
, "Error: invalid cipher: %s.\n", name
);
100 fprintf(stderr
, "Supported ciphers: \n");
101 for (const int *list
= mbedtls_cipher_list(); *list
; list
++) {
102 cipher
= mbedtls_cipher_info_from_type(*list
);
105 fprintf(stderr
, "\t%s\n", mbedtls_cipher_info_get_name(cipher
));
110 int get_cipher_ivsize(const cipher_t
*cipher
)
112 const mbedtls_cipher_info_t
*c
= cipher
;
114 return mbedtls_cipher_info_get_iv_size(c
);
117 int get_cipher_keysize(const cipher_t
*cipher
)
119 const mbedtls_cipher_info_t
*c
= cipher
;
121 return mbedtls_cipher_info_get_key_bitlen(c
) >> 3;
124 ctx_t
*create_ctx(const cipher_t
*cipher
, const unsigned char *key
,
125 const unsigned char *iv
, int enc
, int padding
)
127 mbedtls_cipher_context_t
*ctx
;
128 const mbedtls_cipher_info_t
*cipher_info
=cipher
;
131 ctx
= malloc(sizeof (mbedtls_cipher_context_t
));
133 fprintf (stderr
, "Error: create_ctx: out of memory.\n");
137 mbedtls_cipher_init(ctx
);
138 ret
= mbedtls_cipher_setup(ctx
, cipher_info
);
140 fprintf(stderr
, "Error: mbedtls_cipher_setup: %d\n", ret
);
143 ret
= mbedtls_cipher_setkey(ctx
, key
,
144 (int) mbedtls_cipher_get_key_bitlen(ctx
),
145 enc
? MBEDTLS_ENCRYPT
: MBEDTLS_DECRYPT
);
147 fprintf(stderr
, "Error: mbedtls_cipher_setkey: %d\n", ret
);
151 ret
= mbedtls_cipher_set_iv(ctx
, iv
, mbedtls_cipher_get_iv_size(ctx
));
153 fprintf(stderr
, "Error: mbedtls_cipher_set_iv: %d\n", ret
);
158 if (mbedtls_cipher_info_get_mode(cipher_info
) == MBEDTLS_MODE_CBC
) {
159 ret
= mbedtls_cipher_set_padding_mode(ctx
, padding
?
160 MBEDTLS_PADDING_PKCS7
:
161 MBEDTLS_PADDING_NONE
);
163 fprintf(stderr
, "Error: mbedtls_cipher_set_padding_mode: %d\n",
168 if (mbedtls_cipher_info_get_block_size(cipher_info
) > 1 && padding
) {
170 "Error: mbedTLS only allows padding with CBC ciphers.\n");
175 ret
= mbedtls_cipher_reset(ctx
);
177 fprintf(stderr
, "Error: mbedtls_cipher_reset: %d\n", ret
);
187 int do_crypt(FILE *infile
, FILE *outfile
, ctx_t
*ctx
)
189 unsigned char inbuf
[CRYPT_BUF_SIZE
];
190 unsigned char outbuf
[CRYPT_BUF_SIZE
+ MBEDTLS_MAX_BLOCK_LENGTH
];
191 size_t inlen
, outlen
, step
;
194 if (mbedtls_cipher_get_cipher_mode(ctx
) == MBEDTLS_MODE_ECB
) {
195 step
= mbedtls_cipher_get_block_size(ctx
);
196 if (step
> CRYPT_BUF_SIZE
) {
197 step
= CRYPT_BUF_SIZE
;
200 step
= CRYPT_BUF_SIZE
;
204 inlen
= fread(inbuf
, 1, step
, infile
);
207 ret
= mbedtls_cipher_update(ctx
, inbuf
, inlen
, outbuf
, &outlen
);
209 fprintf(stderr
, "Error: mbedtls_cipher_update: %d\n", ret
);
212 ret
= fwrite(outbuf
, 1, outlen
, outfile
);
214 fprintf(stderr
, "Error: cipher_update short write.\n");
218 ret
= mbedtls_cipher_finish(ctx
, outbuf
, &outlen
);
220 fprintf(stderr
, "Error: mbedtls_cipher_finish: %d\n", ret
);
223 ret
= fwrite(outbuf
, 1, outlen
, outfile
);
225 fprintf(stderr
, "Error: cipher_finish short write.\n");
232 void free_ctx(ctx_t
*ctx
)
235 mbedtls_cipher_free(ctx
);