2 * Copyright (C) 2011-2013 Andre Noll <maan@systemlinux.org>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file gcrypt.c Libgrcypt-based encryption/decryption routines. */
16 #include "crypt_backend.h"
19 //#define GCRYPT_DEBUG 1
21 static bool libgcrypt_has_oaep
;
22 static const char *rsa_decrypt_sexp
;
25 static void dump_buffer(const char *msg
, unsigned char *buf
, int len
)
29 fprintf(stderr
, "%s (%u bytes): ", msg
, len
);
30 for (i
= 0; i
< len
; i
++)
31 fprintf(stderr
, "%02x ", buf
[i
]);
32 fprintf(stderr
, "\n");
35 /** Empty. Define GCRYPT_DEBUG to dump buffers. */
36 #define dump_buffer(a, b, c)
39 void hash_function(const char *data
, unsigned long len
, unsigned char *hash
)
45 gret
= gcry_md_open(&handle
, GCRY_MD_SHA1
, 0);
47 gcry_md_write(handle
, data
, (size_t)len
);
48 gcry_md_final(handle
);
49 md
= gcry_md_read(handle
, GCRY_MD_SHA1
);
51 memcpy(hash
, md
, HASH_SIZE
);
52 gcry_md_close(handle
);
55 void get_random_bytes_or_die(unsigned char *buf
, int num
)
57 gcry_randomize(buf
, (size_t)num
, GCRY_STRONG_RANDOM
);
61 * This is called at the beginning of every program that uses libgcrypt. We
62 * don't have to initialize any random seed here, but we must initialize the
63 * gcrypt library. This task is performed by gcry_check_version() which can
64 * also check that the gcrypt library version is at least the minimal required
65 * version. This function also tells us whether we have to use our own OAEP
68 void init_random_seed_or_die(void)
70 const char *ver
, *req_ver
;
72 ver
= gcry_check_version(NULL
);
74 if (!gcry_check_version(req_ver
)) {
75 PARA_EMERG_LOG("fatal: need at least libgcrypt-%s, have: %s\n",
80 if (gcry_check_version(req_ver
)) {
81 libgcrypt_has_oaep
= true;
82 rsa_decrypt_sexp
= "(enc-val(flags oaep)(rsa(a %m)))";
84 libgcrypt_has_oaep
= false;
85 rsa_decrypt_sexp
= "(enc-val(rsa(a %m)))";
89 /** S-expression for the public part of an RSA key. */
90 #define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))"
91 /** S-expression for a private RSA key. */
92 #define RSA_PRIVKEY_SEXP "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))"
94 /* rfc 3447, appendix B.2 */
95 static void mgf1(unsigned char *seed
, size_t seed_len
, unsigned result_len
,
96 unsigned char *result
)
102 unsigned char octet_string
[4], *rp
= result
, *end
= rp
+ result_len
;
104 assert(result_len
/ HASH_SIZE
< 1ULL << 31);
105 gret
= gcry_md_open(&handle
, GCRY_MD_SHA1
, 0);
107 for (n
= 0; rp
< end
; n
++) {
108 gcry_md_write(handle
, seed
, seed_len
);
109 octet_string
[0] = (unsigned char)((n
>> 24) & 255);
110 octet_string
[1] = (unsigned char)((n
>> 16) & 255);
111 octet_string
[2] = (unsigned char)((n
>> 8)) & 255;
112 octet_string
[3] = (unsigned char)(n
& 255);
113 gcry_md_write(handle
, octet_string
, 4);
114 gcry_md_final(handle
);
115 md
= gcry_md_read(handle
, GCRY_MD_SHA1
);
116 memcpy(rp
, md
, PARA_MIN(HASH_SIZE
, (int)(end
- rp
)));
118 gcry_md_reset(handle
);
120 gcry_md_close(handle
);
123 /** The sha1 hash of an empty file. */
124 static const unsigned char empty_hash
[HASH_SIZE
] =
125 "\xda" "\x39" "\xa3" "\xee" "\x5e"
126 "\x6b" "\x4b" "\x0d" "\x32" "\x55"
127 "\xbf" "\xef" "\x95" "\x60" "\x18"
128 "\x90" "\xaf" "\xd8" "\x07" "\x09";
130 /* rfc3447, section 7.1.1 */
131 static void pad_oaep(unsigned char *in
, size_t in_len
, unsigned char *out
,
134 size_t ps_len
= out_len
- in_len
- 2 * HASH_SIZE
- 2;
135 size_t n
, mask_len
= out_len
- HASH_SIZE
- 1;
136 unsigned char *seed
= out
+ 1, *db
= seed
+ HASH_SIZE
,
137 *ps
= db
+ HASH_SIZE
, *one
= ps
+ ps_len
;
138 unsigned char *db_mask
, seed_mask
[HASH_SIZE
];
140 assert(in_len
<= out_len
- 2 - 2 * HASH_SIZE
);
141 assert(out_len
> 2 * HASH_SIZE
+ 2);
142 PARA_DEBUG_LOG("padding %zu byte input -> %zu byte output\n",
144 dump_buffer("unpadded buffer", in
, in_len
);
147 get_random_bytes_or_die(seed
, HASH_SIZE
);
148 memcpy(db
, empty_hash
, HASH_SIZE
);
149 memset(ps
, 0, ps_len
);
151 memcpy(one
+ 1, in
, in_len
);
152 db_mask
= para_malloc(mask_len
);
153 mgf1(seed
, HASH_SIZE
, mask_len
, db_mask
);
154 for (n
= 0; n
< mask_len
; n
++)
156 mgf1(db
, mask_len
, HASH_SIZE
, seed_mask
);
157 for (n
= 0; n
< HASH_SIZE
; n
++)
158 seed
[n
] ^= seed_mask
[n
];
160 dump_buffer("padded buffer", out
, out_len
);
163 /* rfc 3447, section 7.1.2 */
164 static int unpad_oaep(unsigned char *in
, size_t in_len
, unsigned char *out
,
167 unsigned char *masked_seed
= in
+ 1;
168 unsigned char *db
= in
+ 1 + HASH_SIZE
;
169 unsigned char seed
[HASH_SIZE
], seed_mask
[HASH_SIZE
];
170 unsigned char *db_mask
, *p
;
171 size_t n
, mask_len
= in_len
- HASH_SIZE
- 1;
173 mgf1(db
, mask_len
, HASH_SIZE
, seed_mask
);
174 for (n
= 0; n
< HASH_SIZE
; n
++)
175 seed
[n
] = masked_seed
[n
] ^ seed_mask
[n
];
176 db_mask
= para_malloc(mask_len
);
177 mgf1(seed
, HASH_SIZE
, mask_len
, db_mask
);
178 for (n
= 0; n
< mask_len
; n
++)
181 if (memcmp(db
, empty_hash
, HASH_SIZE
))
183 for (p
= db
+ HASH_SIZE
; p
< in
+ in_len
- 1; p
++)
186 if (p
>= in
+ in_len
- 1)
189 *out_len
= in
+ in_len
- p
;
190 memcpy(out
, p
, *out_len
);
194 struct asymmetric_key
{
199 static const char *gcrypt_strerror(gcry_error_t gret
)
201 return gcry_strerror(gcry_err_code(gret
));
204 static int decode_key(const char *key_file
, const char *header_str
,
205 const char *footer_str
, unsigned char **result
)
209 size_t map_size
, key_size
, blob_size
;
210 unsigned char *blob
= NULL
;
211 char *begin
, *footer
, *key
;
213 ret
= mmap_full_file(key_file
, O_RDONLY
, &map
, &map_size
, NULL
);
217 if (strncmp(map
, header_str
, strlen(header_str
)))
219 footer
= strstr(map
, footer_str
);
223 begin
= map
+ strlen(header_str
);
224 /* skip whitespace at the beginning */
225 for (; begin
< footer
; begin
++) {
226 if (para_isspace(*begin
))
234 key_size
= footer
- begin
;
235 key
= para_malloc(key_size
+ 1);
236 for (i
= 0, j
= 0; begin
+ i
< footer
; i
++) {
237 if (para_isspace(begin
[i
]))
242 //PARA_CRIT_LOG("key: %s\n", key);
243 blob_size
= key_size
* 2;
244 blob
= para_malloc(blob_size
);
245 ret
= base64_decode(key
, blob
, blob_size
);
254 ret2
= para_munmap(map
, map_size
);
255 if (ret
>= 0 && ret2
< 0)
265 /** ASN Types and their code. */
267 /** The next object is an integer. */
268 ASN1_TYPE_INTEGER
= 0x2,
269 /** Bit string object. */
270 ASN1_TYPE_BIT_STRING
= 0x03,
271 /** Keys start with one big type sequence. */
272 ASN1_TYPE_SEQUENCE
= 0x30,
275 /* bit 6 has value 0 */
276 static inline bool is_primitive(unsigned char c
)
278 return ((c
& (1<<6)) == 0);
281 static inline bool is_primitive_integer(unsigned char c
)
283 if (!is_primitive(c
))
285 return ((c
& 0x1f) == ASN1_TYPE_INTEGER
);
288 /* Bit 8 is zero (and bits 7-1 give the length) */
289 static inline bool is_short_form(unsigned char c
)
291 return (c
& 0x80) == 0;
294 static inline int get_short_form_length(unsigned char c
)
299 static inline int get_long_form_num_length_bytes(unsigned char c
)
304 static int find_pubkey_bignum_offset(const unsigned char *data
, int len
)
306 const unsigned char *p
= data
, *end
= data
+ len
;
308 /* the whole thing istarts with one sequence */
309 if (*p
!= ASN1_TYPE_SEQUENCE
)
310 return -E_ASN1_PARSE
;
313 return -E_ASN1_PARSE
;
314 if (is_short_form(*p
))
317 p
+= 1 + get_long_form_num_length_bytes(*p
);
319 return -E_ASN1_PARSE
;
320 /* another sequence containing the object id, skip it */
321 if (*p
!= ASN1_TYPE_SEQUENCE
)
322 return -E_ASN1_PARSE
;
325 return -E_ASN1_PARSE
;
326 if (!is_short_form(*p
))
327 return -E_ASN1_PARSE
;
328 p
+= 1 + get_short_form_length(*p
);
330 return -E_ASN1_PARSE
;
331 /* all numbers are wrapped in a bit string object that follows */
332 if (*p
!= ASN1_TYPE_BIT_STRING
)
333 return -E_ASN1_PARSE
;
336 return -E_ASN1_PARSE
;
337 if (is_short_form(*p
))
340 p
+= 1 + get_long_form_num_length_bytes(*p
);
341 p
++; /* skip number of unused bits in the bit string */
343 return -E_ASN1_PARSE
;
345 /* next, we have a sequence of two integers (n and e) */
346 if (*p
!= ASN1_TYPE_SEQUENCE
)
347 return -E_ASN1_PARSE
;
350 return -E_ASN1_PARSE
;
351 if (is_short_form(*p
))
354 p
+= 1 + get_long_form_num_length_bytes(*p
);
356 return -E_ASN1_PARSE
;
357 if (*p
!= ASN1_TYPE_INTEGER
)
358 return -E_ASN1_PARSE
;
363 * Returns: Number of bytes scanned. This may differ from the value returned via
364 * bn_bytes because the latter does not include the ASN.1 prefix and a leading
365 * zero is not considered as an additional byte for bn_bytes.
367 static int read_bignum(unsigned char *start
, unsigned char *end
, gcry_mpi_t
*bn
,
372 unsigned char *cp
= start
;
374 if (!is_primitive_integer(*cp
))
375 return -E_BAD_PRIVATE_KEY
;
377 if (is_short_form(*cp
)) {
378 bn_size
= get_short_form_length(*cp
);
381 int num_bytes
= get_long_form_num_length_bytes(*cp
);
382 if (cp
+ num_bytes
> end
)
383 return -E_BAD_PRIVATE_KEY
;
384 if (num_bytes
> 4) /* nobody has such a large modulus */
385 return -E_BAD_PRIVATE_KEY
;
388 for (i
= 0; i
< num_bytes
; i
++, cp
++)
389 bn_size
= (bn_size
<< 8) + *cp
;
391 PARA_DEBUG_LOG("bn_size %d (0x%x)\n", bn_size
, bn_size
);
392 gret
= gcry_mpi_scan(bn
, GCRYMPI_FMT_STD
, cp
, bn_size
, NULL
);
394 PARA_ERROR_LOG("%s while scanning n\n",
395 gcry_strerror(gcry_err_code(gret
)));
399 * Don't take the first leading zero into account for the size of the
409 // unsigned char *buf;
410 // gcry_mpi_aprint(GCRYMPI_FMT_HEX, &buf, NULL, *bn);
411 // PARA_CRIT_LOG("bn: %s\n", buf);
415 static int find_privkey_bignum_offset(const unsigned char *data
, int len
)
417 const unsigned char *p
= data
, *end
= data
+ len
;
419 /* like the public key, the whole thing is contained in a sequence */
420 if (*p
!= ASN1_TYPE_SEQUENCE
)
421 return -E_ASN1_PARSE
;
424 return -E_ASN1_PARSE
;
425 if (is_short_form(*p
))
428 p
+= 1 + get_long_form_num_length_bytes(*p
);
430 return -E_ASN1_PARSE
;
432 /* Skip next integer */
433 if (*p
!= ASN1_TYPE_INTEGER
)
434 return -E_ASN1_PARSE
;
437 return -E_ASN1_PARSE
;
438 if (is_short_form(*p
))
439 p
+= 1 + get_short_form_length(*p
);
441 p
+= 1 + get_long_form_num_length_bytes(*p
);
443 return -E_ASN1_PARSE
;
447 /** Private keys start with this header. */
448 #define PRIVATE_KEY_HEADER "-----BEGIN RSA PRIVATE KEY-----"
449 /** Private keys end with this footer. */
450 #define PRIVATE_KEY_FOOTER "-----END RSA PRIVATE KEY-----"
452 static int get_private_key(const char *key_file
, struct asymmetric_key
**result
)
454 gcry_mpi_t n
= NULL
, e
= NULL
, d
= NULL
, p
= NULL
, q
= NULL
,
456 unsigned char *blob
, *cp
, *end
;
457 int blob_size
, ret
, n_size
;
461 struct asymmetric_key
*key
;
463 ret
= decode_key(key_file
, PRIVATE_KEY_HEADER
, PRIVATE_KEY_FOOTER
,
468 end
= blob
+ blob_size
;
469 ret
= find_privkey_bignum_offset(blob
, blob_size
);
472 PARA_INFO_LOG("reading RSA params at offset %d\n", ret
);
475 ret
= read_bignum(cp
, end
, &n
, &n_size
);
480 ret
= read_bignum(cp
, end
, &e
, NULL
);
485 ret
= read_bignum(cp
, end
, &d
, NULL
);
490 ret
= read_bignum(cp
, end
, &p
, NULL
);
495 ret
= read_bignum(cp
, end
, &q
, NULL
);
499 ret
= read_bignum(cp
, end
, &u
, NULL
);
503 * OpenSSL uses slightly different parameters than gcrypt. To use these
504 * parameters we need to swap the values of p and q and recompute u.
506 if (gcry_mpi_cmp(p
, q
) > 0) {
508 gcry_mpi_invm(u
, p
, q
);
510 gret
= gcry_sexp_build(&sexp
, &erroff
, RSA_PRIVKEY_SEXP
,
514 PARA_ERROR_LOG("offset %zu: %s\n", erroff
,
515 gcry_strerror(gcry_err_code(gret
)));
519 key
= para_malloc(sizeof(*key
));
523 PARA_INFO_LOG("succesfully read %d bit private key\n", ret
);
541 /** Public keys start with this header. */
542 #define PUBLIC_KEY_HEADER "-----BEGIN PUBLIC KEY-----"
543 /** Public keys end with this footer. */
544 #define PUBLIC_KEY_FOOTER "-----END PUBLIC KEY-----"
546 static int get_asn_public_key(const char *key_file
, struct asymmetric_key
**result
)
548 gcry_mpi_t n
= NULL
, e
= NULL
;
549 unsigned char *blob
, *cp
, *end
;
550 int blob_size
, ret
, n_size
;
554 struct asymmetric_key
*key
;
556 ret
= decode_key(key_file
, PUBLIC_KEY_HEADER
, PUBLIC_KEY_FOOTER
,
561 end
= blob
+ blob_size
;
562 ret
= find_pubkey_bignum_offset(blob
, blob_size
);
565 PARA_DEBUG_LOG("decoding public RSA params at offset %d\n", ret
);
568 ret
= read_bignum(cp
, end
, &n
, &n_size
);
573 ret
= read_bignum(cp
, end
, &e
, NULL
);
577 gret
= gcry_sexp_build(&sexp
, &erroff
, RSA_PUBKEY_SEXP
, n
, e
);
579 PARA_ERROR_LOG("offset %zu: %s\n", erroff
,
580 gcry_strerror(gcry_err_code(gret
)));
584 key
= para_malloc(sizeof(*key
));
588 PARA_INFO_LOG("successfully read %u bit asn public key\n", n_size
* 8);
599 static int get_ssh_public_key(unsigned char *data
, int size
, gcry_sexp_t
*result
)
603 unsigned char *blob
= NULL
, *p
, *end
;
604 size_t nr_scanned
, erroff
, decoded_size
;
605 gcry_mpi_t e
= NULL
, n
= NULL
;
607 PARA_DEBUG_LOG("decoding %d byte public rsa-ssh key\n", size
);
608 if (size
> INT_MAX
/ 4)
609 return -ERRNO_TO_PARA_ERROR(EOVERFLOW
);
610 blob
= para_malloc(2 * size
);
611 ret
= uudecode((char *)data
, blob
, 2 * size
);
615 end
= blob
+ decoded_size
;
616 dump_buffer("decoded key", blob
, decoded_size
);
617 ret
= check_ssh_key_header(blob
, decoded_size
);
624 PARA_DEBUG_LOG("scanning modulus and public exponent\n");
625 gret
= gcry_mpi_scan(&e
, GCRYMPI_FMT_SSH
, p
, end
- p
, &nr_scanned
);
628 PARA_CRIT_LOG("%s\n", gcry_strerror(gcry_err_code(gret
)));
631 PARA_DEBUG_LOG("scanned e (%zu bytes)\n", nr_scanned
);
632 // gcry_mpi_aprint(GCRYMPI_FMT_HEX, &buf, NULL, rsa_e);
633 // PARA_CRIT_LOG("e: %s\n", buf);
637 gret
= gcry_mpi_scan(&n
, GCRYMPI_FMT_SSH
, p
, end
- p
, &nr_scanned
);
640 PARA_ERROR_LOG("%s\n", gcry_strerror(gcry_err_code(gret
)));
643 PARA_DEBUG_LOG("scanned n (%zu bytes)\n", nr_scanned
);
644 // gcry_mpi_aprint(GCRYMPI_FMT_HEX, &buf, NULL, rsa_n);
645 // PARA_CRIT_LOG("n: %s\n", buf);
646 gret
= gcry_sexp_build(result
, &erroff
, RSA_PUBKEY_SEXP
, n
, e
);
648 PARA_ERROR_LOG("offset %zu: %s\n", erroff
,
649 gcry_strerror(gcry_err_code(gret
)));
653 ret
= nr_scanned
/ 32 * 32;
654 PARA_INFO_LOG("successfully read %u bit ssh public key\n", ret
* 8);
664 int get_asymmetric_key(const char *key_file
, int private,
665 struct asymmetric_key
**result
)
670 unsigned char *start
, *end
;
672 struct asymmetric_key
*key
;
675 return get_private_key(key_file
, result
);
676 ret
= mmap_full_file(key_file
, O_RDONLY
, &map
, &map_size
, NULL
);
679 ret
= is_ssh_rsa_key(map
, map_size
);
681 ret
= para_munmap(map
, map_size
);
684 return get_asn_public_key(key_file
, result
);
687 end
= map
+ map_size
;
691 ret
= get_ssh_public_key(start
, end
- start
, &sexp
);
694 key
= para_malloc(sizeof(*key
));
695 key
->num_bytes
= ret
;
699 ret2
= para_munmap(map
, map_size
);
700 if (ret
>= 0 && ret2
< 0)
705 void free_asymmetric_key(struct asymmetric_key
*key
)
709 gcry_sexp_release(key
->sexp
);
713 static int decode_rsa(gcry_sexp_t sexp
, int key_size
, unsigned char *outbuf
,
718 unsigned char oaep_buf
[512];
721 if (libgcrypt_has_oaep
) {
722 const char *p
= gcry_sexp_nth_data(sexp
, 1, nbytes
);
725 PARA_ERROR_LOG("could not get data from list\n");
728 memcpy(outbuf
, p
, *nbytes
);
731 out_mpi
= gcry_sexp_nth_mpi(sexp
, 0, GCRYMPI_FMT_USG
);
734 gret
= gcry_mpi_print(GCRYMPI_FMT_USG
, oaep_buf
, sizeof(oaep_buf
),
737 PARA_ERROR_LOG("mpi_print: %s\n", gcrypt_strerror(gret
));
739 goto out_mpi_release
;
742 * An oaep-encoded buffer always starts with at least one zero byte.
743 * However, leading zeroes in an mpi are omitted in the output of
744 * gcry_mpi_print() when using the GCRYMPI_FMT_USG format. The
745 * alternative, GCRYMPI_FMT_STD, does not work either because here the
746 * leading zero(es) might also be omitted, depending on the value of
749 * To circumvent this, we shift the oaep buffer to the right. But first
750 * we check that the buffer actually started with a zero byte, i.e. that
751 * nbytes < key_size. Otherwise a decoding error occurred.
753 ret
= -E_SEXP_DECRYPT
;
754 if (*nbytes
>= key_size
)
755 goto out_mpi_release
;
756 memmove(oaep_buf
+ key_size
- *nbytes
, oaep_buf
, *nbytes
);
757 memset(oaep_buf
, 0, key_size
- *nbytes
);
759 PARA_DEBUG_LOG("decrypted buffer before unpad (%d bytes):\n",
761 dump_buffer("non-unpadded decrypted buffer", oaep_buf
, key_size
);
762 ret
= unpad_oaep(oaep_buf
, key_size
, outbuf
, nbytes
);
764 goto out_mpi_release
;
765 PARA_DEBUG_LOG("decrypted buffer after unpad (%zu bytes):\n",
767 dump_buffer("unpadded decrypted buffer", outbuf
, *nbytes
);
770 gcry_mpi_release(out_mpi
);
774 int priv_decrypt(const char *key_file
, unsigned char *outbuf
,
775 unsigned char *inbuf
, int inlen
)
779 struct asymmetric_key
*priv
;
780 gcry_mpi_t in_mpi
= NULL
;
781 gcry_sexp_t in
, out
, priv_key
;
784 PARA_INFO_LOG("decrypting %d byte input\n", inlen
);
785 /* key_file -> asymmetric key priv */
786 ret
= get_private_key(key_file
, &priv
);
791 /* asymmetric key priv -> sexp priv_key */
793 priv_key
= gcry_sexp_find_token(priv
->sexp
, "private-key", 0);
797 /* inbuf -> in_mpi */
798 gret
= gcry_mpi_scan(&in_mpi
, GCRYMPI_FMT_USG
, inbuf
,
801 PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret
));
805 /* in_mpi -> in sexp */
806 gret
= gcry_sexp_build(&in
, NULL
, rsa_decrypt_sexp
, in_mpi
);
808 PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret
));
813 /* rsa decryption: in sexp -> out sexp */
814 gret
= gcry_pk_decrypt(&out
, in
, priv_key
);
816 PARA_ERROR_LOG("decrypt: %s\n", gcrypt_strerror(gret
));
817 ret
= -E_SEXP_DECRYPT
;
820 ret
= decode_rsa(out
, key_size
, outbuf
, &nbytes
);
823 PARA_INFO_LOG("successfully decrypted %zu byte message\n", nbytes
);
826 gcry_sexp_release(out
);
828 gcry_sexp_release(in
);
830 gcry_mpi_release(in_mpi
);
832 gcry_sexp_release(priv_key
);
834 free_asymmetric_key(priv
);
838 int pub_encrypt(struct asymmetric_key
*pub
, unsigned char *inbuf
,
839 unsigned len
, unsigned char *outbuf
)
842 gcry_sexp_t pub_key
, in
, out
, out_a
;
843 gcry_mpi_t out_mpi
= NULL
;
847 PARA_INFO_LOG("encrypting %u byte input with %d-byte key\n", len
, pub
->num_bytes
);
850 pub_key
= gcry_sexp_find_token(pub
->sexp
, "public-key", 0);
853 if (libgcrypt_has_oaep
) {
854 gret
= gcry_sexp_build(&in
, NULL
,
855 "(data(flags oaep)(value %b))", len
, inbuf
);
857 unsigned char padded_input
[256];
858 const size_t pad_size
= 256;
859 /* inbuf -> padded inbuf */
860 pad_oaep(inbuf
, len
, padded_input
, pad_size
);
861 /* padded inbuf -> in sexp */
862 gret
= gcry_sexp_build(&in
, NULL
,
863 "(data(flags raw)(value %b))", pad_size
, padded_input
);
866 PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret
));
870 /* rsa sexp encryption: in -> out */
871 gret
= gcry_pk_encrypt(&out
, in
, pub_key
);
873 PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret
));
874 ret
= -E_SEXP_ENCRYPT
;
877 /* extract a, an MPI with the result of the RSA operation */
879 out_a
= gcry_sexp_find_token(out
, "a", 0);
882 /* convert sexp out_a -> out_mpi */
883 out_mpi
= gcry_sexp_nth_mpi(out_a
, 1, GCRYMPI_FMT_USG
);
888 gret
= gcry_mpi_print(GCRYMPI_FMT_USG
, outbuf
, 512 /* FIXME */, &nbytes
, out_mpi
);
890 PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret
));
891 ret
= -E_SEXP_ENCRYPT
;
892 goto out_mpi_release
;
894 PARA_INFO_LOG("encrypted buffer is %zu bytes\n", nbytes
);
895 dump_buffer("enc buf", outbuf
, nbytes
);
899 gcry_mpi_release(out_mpi
);
901 gcry_sexp_release(out_a
);
903 gcry_sexp_release(out
);
905 gcry_sexp_release(in
);
907 gcry_sexp_release(pub_key
);
911 struct stream_cipher
{
912 gcry_cipher_hd_t handle
;
915 struct stream_cipher
*sc_new(const unsigned char *data
, int len
)
919 struct stream_cipher
*sc
= para_malloc(sizeof(*sc
));
920 gret
= gcry_cipher_open(&sc
->handle
, GCRY_CIPHER_ARCFOUR
,
921 GCRY_CIPHER_MODE_STREAM
, 0);
923 PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret
));
927 gret
= gcry_cipher_setkey(sc
->handle
, data
, (size_t)len
);
932 void sc_free(struct stream_cipher
*sc
)
936 gcry_cipher_close(sc
->handle
);
940 void sc_crypt(struct stream_cipher
*sc
, struct iovec
*src
, struct iovec
*dst
)
942 gcry_cipher_hd_t handle
= sc
->handle
;
945 /* perform in-place encryption */
947 gret
= gcry_cipher_encrypt(handle
, src
->iov_base
, src
->iov_len
,