1 /* encrypt.c - Encrypt a message
2 * Copyright (C) 2001, 2003, 2004, 2007, 2008,
3 * 2010 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
35 #include "../common/i18n.h"
36 #include "../common/compliance.h"
48 typedef struct dek_s *DEK;
51 /* Callback parameters for the encryption. */
52 struct encrypt_cb_parm_s
60 unsigned char *buffer;
68 /* Initialize the data encryption key (session key). */
74 dek->algo = gcry_cipher_map_name (dek->algoid);
75 mode = gcry_cipher_mode_from_oid (dek->algoid);
76 if (!dek->algo || !mode)
78 log_error ("unsupported algorithm '%s'\n", dek->algoid);
79 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
82 /* Extra check for algorithms we consider to be too weak for
83 encryption, although we support them for decryption. Note that
84 there is another check below discriminating on the key length. */
88 case GCRY_CIPHER_RFC2268_40:
89 log_error ("cipher algorithm '%s' not allowed: too weak\n",
90 gnupg_cipher_algo_name (dek->algo));
91 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
96 dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
97 if (!dek->keylen || dek->keylen > sizeof (dek->key))
98 return gpg_error (GPG_ERR_BUG);
100 dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo);
101 if (!dek->ivlen || dek->ivlen > sizeof (dek->iv))
102 return gpg_error (GPG_ERR_BUG);
104 /* Make sure we don't use weak keys. */
105 if (dek->keylen < 100/8)
107 log_error ("key length of '%s' too small\n", dek->algoid);
108 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
111 rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
114 log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
118 for (i=0; i < 8; i++)
120 gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
121 rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen);
122 if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
124 log_info(_("weak key created - retrying\n") );
128 log_error ("failed to set the key: %s\n", gpg_strerror (rc));
129 gcry_cipher_close (dek->chd);
134 gcry_create_nonce (dek->iv, dek->ivlen);
135 rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen);
138 log_error ("failed to set the IV: %s\n", gpg_strerror (rc));
139 gcry_cipher_close (dek->chd);
149 encode_session_key (DEK dek, gcry_sexp_t * r_data)
155 p = xtrymalloc (64 + 2 * dek->keylen);
157 return gpg_error_from_syserror ();
158 strcpy (p, "(data\n (flags pkcs1)\n (value #");
159 bin2hex (dek->key, dek->keylen, p + strlen (p));
161 rc = gcry_sexp_sscan (&data, NULL, p, strlen (p));
168 /* Encrypt the DEK under the key contained in CERT and return it as a
169 canonical S-Exp in encval. */
171 encrypt_dek (const DEK dek, ksba_cert_t cert, unsigned char **encval)
173 gcry_sexp_t s_ciph, s_data, s_pkey;
180 /* get the key from the cert */
181 buf = ksba_cert_get_public_key (cert);
184 log_error ("no public key for recipient\n");
185 return gpg_error (GPG_ERR_NO_PUBKEY);
187 len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
190 log_error ("libksba did not return a proper S-Exp\n");
191 return gpg_error (GPG_ERR_BUG);
193 rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)buf, len);
194 xfree (buf); buf = NULL;
197 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
201 /* Put the encoded cleartext into a simple list. */
202 s_data = NULL; /* (avoid compiler warning) */
203 rc = encode_session_key (dek, &s_data);
206 log_error ("encode_session_key failed: %s\n", gpg_strerror (rc));
210 /* pass it to libgcrypt */
211 rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
212 gcry_sexp_release (s_data);
213 gcry_sexp_release (s_pkey);
218 rc = make_canon_sexp (s_ciph, encval, NULL);
219 gcry_sexp_release (s_ciph);
226 /* do the actual encryption */
228 encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
230 struct encrypt_cb_parm_s *parm = cb_value;
231 int blklen = parm->dek->ivlen;
237 return -1; /* not supported */
246 { /* fillup the buffer */
248 for (n=parm->buflen; n < parm->bufsize; n++)
250 int c = es_getc (parm->fp);
253 if (es_ferror (parm->fp))
255 parm->readerror = errno;
266 n = parm->buflen < count? parm->buflen : count;
267 n = n/blklen * blklen;
269 { /* encrypt the stuff */
270 gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
272 /* Who cares about cycles, take the easy way and shift the buffer */
274 memmove (parm->buffer, parm->buffer+n, parm->buflen);
276 else if (parm->eof_seen)
277 { /* no complete block but eof: add padding */
278 /* fixme: we should try to do this also in the above code path */
279 int i, npad = blklen - (parm->buflen % blklen);
281 for (n=parm->buflen, i=0; n < parm->bufsize && i < npad; n++, i++)
283 gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
294 /* Perform an encrypt operation.
296 Encrypt the data received on DATA-FD and write it to OUT_FP. The
297 recipients are take from the certificate given in recplist; if this
298 is NULL it will be encrypted for a default recipient */
300 gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
303 gnupg_ksba_io_t b64writer = NULL;
305 ksba_writer_t writer;
306 ksba_reader_t reader = NULL;
307 ksba_cms_t cms = NULL;
308 ksba_stop_reason_t stopreason;
309 KEYDB_HANDLE kh = NULL;
310 struct encrypt_cb_parm_s encparm;
313 estream_t data_fp = NULL;
318 memset (&encparm, 0, sizeof encparm);
320 audit_set_type (ctrl->audit, AUDIT_TYPE_ENCRYPT);
322 /* Check that the certificate list is not empty and that at least
323 one certificate is not flagged as encrypt_to; i.e. is a real
325 for (cl = recplist; cl; cl = cl->next)
326 if (!cl->is_encrypt_to)
330 log_error(_("no valid recipients given\n"));
331 gpgsm_status (ctrl, STATUS_NO_RECP, "0");
332 audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, 0);
333 rc = gpg_error (GPG_ERR_NO_PUBKEY);
337 for (count = 0, cl = recplist; cl; cl = cl->next)
339 audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, count);
344 log_error (_("failed to allocate keyDB handle\n"));
345 rc = gpg_error (GPG_ERR_GENERAL);
349 /* Fixme: We should use the unlocked version of the es functions. */
350 data_fp = es_fdopen_nc (data_fd, "rb");
353 rc = gpg_error_from_syserror ();
354 log_error ("fdopen() failed: %s\n", strerror (errno));
358 err = ksba_reader_new (&reader);
362 rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm);
366 encparm.fp = data_fp;
368 ctrl->pem_name = "ENCRYPTED MESSAGE";
369 rc = gnupg_ksba_create_writer
370 (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0)
371 | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)),
372 ctrl->pem_name, out_fp, &writer);
375 log_error ("can't create writer: %s\n", gpg_strerror (rc));
379 err = ksba_cms_new (&cms);
386 err = ksba_cms_set_reader_writer (cms, reader, writer);
389 log_debug ("ksba_cms_set_reader_writer failed: %s\n",
395 audit_log (ctrl->audit, AUDIT_GOT_DATA);
397 /* We are going to create enveloped data with uninterpreted data as
399 err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
401 err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
404 log_debug ("ksba_cms_set_content_type failed: %s\n",
410 /* Check compliance. */
411 if (!gnupg_cipher_is_allowed
412 (opt.compliance, 1, gcry_cipher_map_name (opt.def_cipher_algoid),
413 gcry_cipher_mode_from_oid (opt.def_cipher_algoid)))
415 log_error (_("you may not use cipher algorithm '%s'"
416 " while in %s mode\n"),
417 opt.def_cipher_algoid,
418 gnupg_compliance_option_string (opt.compliance));
419 rc = gpg_error (GPG_ERR_CIPHER_ALGO);
423 if (!gnupg_rng_is_compliant (opt.compliance))
425 rc = gpg_error (GPG_ERR_FORBIDDEN);
426 log_error (_("%s is not compliant with %s mode\n"),
428 gnupg_compliance_option_string (opt.compliance));
429 gpgsm_status_with_error (ctrl, STATUS_ERROR,
430 "random-compliance", rc);
434 /* Create a session key */
435 dek = xtrycalloc_secure (1, sizeof *dek);
440 dek->algoid = opt.def_cipher_algoid;
445 log_error ("failed to create the session key: %s\n",
450 err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen);
453 log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
460 /* Use a ~8k (AES) or ~4k (3DES) buffer */
461 encparm.bufsize = 500 * dek->ivlen;
462 encparm.buffer = xtrymalloc (encparm.bufsize);
469 audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);
471 compliant = gnupg_cipher_is_compliant (CO_DE_VS, dek->algo,
472 GCRY_CIPHER_MODE_CBC);
474 /* Gather certificates of recipients, encrypt the session key for
475 each and store them in the CMS object */
476 for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
478 unsigned char *encval;
482 /* Check compliance. */
483 pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
484 if (!gnupg_pk_is_compliant (opt.compliance, pk_algo, NULL, nbits, NULL))
488 snprintf (kidstr, sizeof kidstr, "0x%08lX",
489 gpgsm_get_short_fingerprint (cl->cert, NULL));
490 log_info (_("WARNING: key %s is not suitable for encryption"
493 gnupg_compliance_option_string (opt.compliance));
496 /* Fixme: When adding ECC we need to provide the curvename and
497 * the key to gnupg_pk_is_compliant. */
499 && !gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL, nbits, NULL))
502 rc = encrypt_dek (dek, cl->cert, &encval);
505 audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, rc);
506 log_error ("encryption failed for recipient no. %d: %s\n",
507 recpno, gpg_strerror (rc));
511 err = ksba_cms_add_recipient (cms, cl->cert);
514 audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
515 log_error ("ksba_cms_add_recipient failed: %s\n",
522 err = ksba_cms_set_enc_val (cms, recpno, encval);
524 audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
527 log_error ("ksba_cms_set_enc_val failed: %s\n",
535 gpgsm_status (ctrl, STATUS_ENCRYPTION_COMPLIANCE_MODE,
536 gnupg_status_compliance_flag (CO_DE_VS));
538 /* Main control loop for encryption. */
542 err = ksba_cms_build (cms, &stopreason);
545 log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err));
550 while (stopreason != KSBA_SR_READY);
552 if (encparm.readerror)
554 log_error ("error reading input: %s\n", strerror (encparm.readerror));
555 rc = gpg_error (gpg_err_code_from_errno (encparm.readerror));
560 rc = gnupg_ksba_finish_writer (b64writer);
563 log_error ("write failed: %s\n", gpg_strerror (rc));
566 audit_log (ctrl->audit, AUDIT_ENCRYPTION_DONE);
567 log_info ("encrypted data created\n");
570 ksba_cms_release (cms);
571 gnupg_ksba_destroy_writer (b64writer);
572 ksba_reader_release (reader);
576 xfree (encparm.buffer);