From cvs at cvs.gnupg.org Mon Jan 1 15:04:41 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 01 Jan 2018 15:04:41 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-7-g4d3c500 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 4d3c500f4793eb263940ff5ef87ec4ead63c9b4b (commit) from 412bb7a801f242d47a82712080cce6ddbb843166 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4d3c500f4793eb263940ff5ef87ec4ead63c9b4b Author: Werner Koch Date: Mon Jan 1 14:59:30 2018 +0100 gpg: Allow "futuredefault" as alias for "future-default". * g10/keygen.c (parse_key_parameter_string): Allow "futuredefault" and use case-insensitive matching (quick_generate_keypair): Ditto. (parse_algo_usage_expire): Ditto. -- The man page is sometimes rendered in a way that the hyphen may be not be considered as part of the string. And while at it we also allow case-insensitivity. GnuPG-bug-id: 3655 Signed-off-by: Werner Koch diff --git a/g10/keygen.c b/g10/keygen.c index a79b4fb..01f3de0 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3153,9 +3153,10 @@ parse_key_parameter_string (const char *string, int part, *r_subcurve = NULL; if (!string || !*string - || !strcmp (string, "default") || !strcmp (string, "-")) + || !ascii_strcasecmp (string, "default") || !strcmp (string, "-")) string = get_default_pubkey_algo (); - else if (!strcmp (string, "future-default")) + else if (!ascii_strcasecmp (string, "future-default") + || !ascii_strcasecmp (string, "futuredefault")) string = FUTURE_STD_KEY_PARAM; primary = xstrdup (string); @@ -3984,9 +3985,10 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr, if (!*expirestr || strcmp (expirestr, "-") == 0) expirestr = default_expiration_interval; - if ((!*algostr || !strcmp (algostr, "default") - || !strcmp (algostr, "future-default")) - && (!*usagestr || !strcmp (usagestr, "default") + if ((!*algostr || !ascii_strcasecmp (algostr, "default") + || !ascii_strcasecmp (algostr, "future-default") + || !ascii_strcasecmp (algostr, "futuredefault")) + && (!*usagestr || !ascii_strcasecmp (usagestr, "default") || !strcmp (usagestr, "-"))) { /* Use default key parameters. */ @@ -4928,7 +4930,7 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey, /* Parse the usage string. */ if (!usagestr || !*usagestr - || !strcmp (usagestr, "default") || !strcmp (usagestr, "-")) + || !ascii_strcasecmp (usagestr, "default") || !strcmp (usagestr, "-")) ; /* Keep usage from parse_key_parameter_string. */ else if ((wantuse = parse_usagestr (usagestr)) != -1) use = wantuse; ----------------------------------------------------------------------- Summary of changes: g10/keygen.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 2 11:20:28 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 02 Jan 2018 11:20:28 +0100 Subject: [git] gnupg-doc - branch, master, updated. 2f320018cc0c255a11e15609632b7e1b4d381d2f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 2f320018cc0c255a11e15609632b7e1b4d381d2f (commit) from 4e3196a2172dc037fe8889bd21d50115e5a02663 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f320018cc0c255a11e15609632b7e1b4d381d2f Author: Werner Koch Date: Tue Jan 2 11:15:36 2018 +0100 build: Also render the gnupg.org as plain text. * web/share/gpgweb.el (gpgweb-faq-to-txt): New. * tools/build-website.sh: Call new function. -- We had to do this in the past manually and it was oftne forgooten which led to some confusion. diff --git a/tools/build-website.sh b/tools/build-website.sh index 2f8ceb9..6e2842d 100755 --- a/tools/build-website.sh +++ b/tools/build-website.sh @@ -163,7 +163,8 @@ else --eval "(gpgweb-setup-project)" \ --eval "(org-publish-initialize-cache \"gpgweb\")" \ --eval "(message \"root=(%s)\" gpgweb-root-dir)" \ - --eval "(org-publish \"gpgweb\" t nil)" + --eval "(org-publish \"gpgweb\" t nil)" \ + --eval "(gpgweb-faq-to-txt \"gnupg-faq.org\")" echo "$rev" > ${revlastfile} sync_web=${stage_dir}/${subdir} diff --git a/web/share/gpgweb.el b/web/share/gpgweb.el index 6539206..2651c35 100644 --- a/web/share/gpgweb.el +++ b/web/share/gpgweb.el @@ -478,6 +478,23 @@ to create the previous and Next links for an entry." nil)) +(defun gpgweb-faq-to-txt (faqfile) + "Render FAQFILE as text. FAQFILE is assumed to be in web/faq. +Note that the HTML rendering is done as part of the gpgweb-org-to-html" + (interactive "sFAQ orgfile: ") + (let* ((file (concat gpgweb-root-dir "faq/" faqfile)) + (visitingp (find-buffer-visiting file)) + (work-buffer (or visitingp (find-file-noselect file)))) + (with-current-buffer work-buffer + (setq default-directory (concat gpgweb-stage-dir "faq")) + (make-directory default-directory t) + (toggle-read-only 0) + (org-ascii-export-to-ascii nil nil nil nil '(:ascii-charset utf-8)) + (basic-save-buffer)) + (unless visitingp + (kill-buffer work-buffer)))) + + (defun gpgweb-render-blog (&optional filelist) "Turn the current buffer which has an org-mode blog entry into its rendered form and save it with the suffix .html." @@ -508,7 +525,6 @@ rendered form and save it with the suffix .html." (unless visitingp (kill-buffer work-buffer)))))) - (defun gpgweb-upload () "We don't do an upload directly. Instead we only print the commands to do that. In reality a cron jobs syncs the stage dir." ----------------------------------------------------------------------- Summary of changes: tools/build-website.sh | 3 ++- web/share/gpgweb.el | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 2 12:15:56 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 02 Jan 2018 12:15:56 +0100 Subject: [git] gnupg-doc - branch, master, updated. 31395cff13e055cce19af7d47eb53c6a9d7ea704 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 31395cff13e055cce19af7d47eb53c6a9d7ea704 (commit) from 2f320018cc0c255a11e15609632b7e1b4d381d2f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 31395cff13e055cce19af7d47eb53c6a9d7ea704 Author: Werner Koch Date: Tue Jan 2 12:11:04 2018 +0100 verein: Update finances diff --git a/web/verein/finances.org b/web/verein/finances.org index 6c33f48..b5af434 100644 --- a/web/verein/finances.org +++ b/web/verein/finances.org @@ -12,7 +12,7 @@ ** Euro transaction - Here are the transactions on our bank account. +Here are the transactions on our bank account in 2017 | Date | Debit | Credit | Balance | Description | |------------+----------+--------+-----------+--------------------------| @@ -31,6 +31,10 @@ | 2017-10-06 | 18197.53 | | 157386.58 | Exchange of 5 BTC | | 2017-10-12 | 220.00 | | 157606.58 | Donation kernel-recipes | | 2017-10-12 | 310.00 | | 157916.58 | Donation kernel-recipes | +| 2017-10-28 | | 6.20 | 157910.38 | Bank fees | +| 2017-11-30 | | 5.00 | 157905.38 | Bank fees | +| 2017-12-29 | | 5.00 | 157900.38 | Bank fees | +|------------+----------+--------+-----------+--------------------------| The 59.000 ? from the Wau Holland Stiftung have been collected by them @@ -43,5 +47,5 @@ printing costs. ** Bitcoin transactions - As of 2017-10-06 we own 0.12 BTC. 26 BTC have been - transferred to our Euro account (see above). +As of 2018-01-02 we own 0.4608 confirmed BTC. 26 BTC have been +transferred to our Euro account in September/October 2017 (see above). ----------------------------------------------------------------------- Summary of changes: web/verein/finances.org | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 5 11:56:34 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 05 Jan 2018 11:56:34 +0100 Subject: [git] gnupg-doc - branch, master, updated. b02c609919cf523f0e09aba7ea08d06ca4c12ce1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via b02c609919cf523f0e09aba7ea08d06ca4c12ce1 (commit) from 31395cff13e055cce19af7d47eb53c6a9d7ea704 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b02c609919cf523f0e09aba7ea08d06ca4c12ce1 Author: Werner Koch Date: Fri Jan 5 11:51:38 2018 +0100 drafts,openpgp-webkey-service: Typo fix diff --git a/misc/id/openpgp-webkey-service/draft.org b/misc/id/openpgp-webkey-service/draft.org index fb0eb60..5a1846b 100644 --- a/misc/id/openpgp-webkey-service/draft.org +++ b/misc/id/openpgp-webkey-service/draft.org @@ -420,7 +420,7 @@ A site supporting the Web Key Directory MUST serve this file; it is sufficient if that file has a zero length. Clients may use this file to check for Web Key Directory support. -The file contains keywords and optioanlly values, one per line with +The file contains keywords and optionally values, one per line with each line terminated by a LF or the sequence of CR and LF. Empty lines and lines starting with a '#' character are considered comment lines. A keyword is made up of lowercase letters, digits, hyphens, or ----------------------------------------------------------------------- Summary of changes: misc/id/openpgp-webkey-service/draft.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 5 13:26:57 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 05 Jan 2018 13:26:57 +0100 Subject: [git] gnupg-doc - branch, master, updated. f7156272064eb08432fe39280d23f2ac4b0810b5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via f7156272064eb08432fe39280d23f2ac4b0810b5 (commit) from b02c609919cf523f0e09aba7ea08d06ca4c12ce1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f7156272064eb08432fe39280d23f2ac4b0810b5 Author: Werner Koch Date: Fri Jan 5 13:22:01 2018 +0100 drafts,openpgp-webkey-service: Suggest not to create an index file. Suggested-by: Bernhard Reiter diff --git a/misc/id/openpgp-webkey-service/draft.org b/misc/id/openpgp-webkey-service/draft.org index 5a1846b..7d3c740 100644 --- a/misc/id/openpgp-webkey-service/draft.org +++ b/misc/id/openpgp-webkey-service/draft.org @@ -482,6 +482,10 @@ over all keys. An implementation may want to weight the certainty of a mapping different if it has been retrieved via a sub-domain and in particular if a non-recommended name is used for the sub-domain. +To make it a bit harder to test for published keys, the server +responsible to serve the WELLKNOWN directory SHOULD NOT create an +index file for that directory or any sub-directory. + * IANA Considerations ----------------------------------------------------------------------- Summary of changes: misc/id/openpgp-webkey-service/draft.org | 4 ++++ 1 file changed, 4 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 8 09:39:32 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 08 Jan 2018 09:39:32 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-8-g339b330 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 339b3301ee8410fe3bbdebb66a6e83801d79d40d (commit) from 4d3c500f4793eb263940ff5ef87ec4ead63c9b4b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 339b3301ee8410fe3bbdebb66a6e83801d79d40d Author: Werner Koch Date: Mon Jan 8 09:30:31 2018 +0100 gpg: Print all keys with --decrypt --list-only. * g10/mainproc.c (proc_pubkey_enc): Use dedicated error code for list-only and put the key into PKENC_LIST. (print_pkenc_list): Take care of the new error code. -- If the secret keys exist in --list-only mode it was not printed in --list-only mode. GnuPG-bug-id: 3718 Signed-off-by: Werner Koch diff --git a/g10/mainproc.c b/g10/mainproc.c index b712e60..512d33c 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -422,7 +422,7 @@ proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) || have_secret_key_with_kid (enc->keyid))) { if(opt.list_only) - result = -1; + result = GPG_ERR_MISSING_ACTION; /* fixme: Use better error code. */ else { c->dek = xmalloc_secure_clear (sizeof *c->dek); @@ -440,9 +440,7 @@ proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) else result = GPG_ERR_PUBKEY_ALGO; - if (result == -1) - ; - else + if (1) { /* Store it for later display. */ struct kidlist_item *x = xmalloc (sizeof *x); @@ -510,6 +508,10 @@ print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list, int failed) write_status_text (STATUS_NO_SECKEY, buf); } } + else if (gpg_err_code (list->reason) == GPG_ERR_MISSING_ACTION) + { + /* Not tested for secret key due to --list-only mode. */ + } else if (list->reason) { log_info (_("public key decryption failed: %s\n"), ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 8 11:26:33 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 08 Jan 2018 11:26:33 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-7-gdf029bc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via df029bca0eecd11f78bd0ef95360d0f37cb4b9d5 (commit) via f892c4d19cf7c1b3d885fdbcc417fba380b3d363 (commit) via ef015c7a53fedb004ff0c049add887def231957b (commit) from b8276a4f3acecee2e467c0530007aedc9db5936a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit df029bca0eecd11f78bd0ef95360d0f37cb4b9d5 Author: Andre Heinecke Date: Mon Jan 8 11:21:29 2018 +0100 Fix return type for mails with override msgcls * src/mapihelp.cpp (mapi_change_message_class): Improve logging in override case. (mapi_change_message_class): Ensure r_type is set correctly. -- This fixes some cases where the message class was already set. Apparently this happens on Exchange / Exchange Online as I was only able to reproduce the problem there. It might happen in other set ups where the server already stores our GpgOL message class. GnuPG-Bug-Id: T3537 diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index 952ddd6..a9c69c3 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -1378,9 +1378,30 @@ mapi_change_message_class (LPMESSAGE message, int sync_override, hr = HrGetOneProp ((LPMAPIPROP)message, PR_MESSAGE_CLASS_A, &propval2); - if (SUCCEEDED (hr) && PROP_TYPE (propval2->ulPropTag) == PT_STRING8 - && propval2->Value.lpszA && strcmp (propval2->Value.lpszA, s)) - newvalue = (char*)xstrdup (s); + if (!SUCCEEDED (hr)) + { + log_debug ("%s:%s: Failed to get PR_MESSAGE_CLASS_A property.", + SRCNAME, __func__); + } + else if (PROP_TYPE (propval2->ulPropTag) != PT_STRING8) + { + log_debug ("%s:%s: PR_MESSAGE_CLASS_A is not string.", + SRCNAME, __func__); + } + else if (!propval2->Value.lpszA) + { + log_debug ("%s:%s: PR_MESSAGE_CLASS_A is null.", + SRCNAME, __func__); + } + else if (!strcmp (propval2->Value.lpszA, s)) + { + log_debug ("%s:%s: PR_MESSAGE_CLASS_A is already the same.", + SRCNAME, __func__); + } + else + { + newvalue = (char*)xstrdup (s); + } MAPIFreeBuffer (propval2); } else if (opt.enable_smime @@ -1390,7 +1411,7 @@ mapi_change_message_class (LPMESSAGE message, int sync_override, newvalue = change_message_class_ipm_note_secure_cex (message, cexenc); } - else if (r_type) + if (r_type && !newvalue) { *r_type = string_to_type (s); } @@ -1408,7 +1429,7 @@ mapi_change_message_class (LPMESSAGE message, int sync_override, } else { - if (r_type && newvalue) + if (r_type) { *r_type = string_to_type (newvalue); } commit f892c4d19cf7c1b3d885fdbcc417fba380b3d363 Author: Andre Heinecke Date: Mon Jan 8 11:19:38 2018 +0100 Improve some debug outputs * src/mail.cpp(Mail::pre_process_message): Log item ptr. (Mail::decrypt_verify): Log on bailout for non crypto mail. * src/mailitem-events.cpp (EVENT_SINK_INVOKE(MailItemEvents)): Log on bailout for non crypto mail. diff --git a/src/mail.cpp b/src/mail.cpp index e0f988a..114e65c 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -256,8 +256,8 @@ Mail::pre_process_message () SRCNAME, __func__); return 0; } - log_oom_extra ("%s:%s: GetBaseMessage OK.", - SRCNAME, __func__); + log_oom_extra ("%s:%s: GetBaseMessage OK for %p.", + SRCNAME, __func__, m_mailitem); /* Change the message class here. It is important that we change the message class in the before read event regardless if it is already set to one of GpgOL's message @@ -739,6 +739,8 @@ Mail::decrypt_verify() { if (!is_crypto_mail()) { + log_debug ("%s:%s: Decrypt Verify for non crypto mail: %p.", + SRCNAME, __func__, m_mailitem); return 0; } if (m_needs_wipe) diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index e45299d..ae4aa66 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -189,6 +189,8 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__, m_mail); if (!m_mail->is_crypto_mail()) { + log_debug ("%s:%s: Non crypto mail %p opened. Updating sigstatus.", + SRCNAME, __func__, m_mail); /* Ensure that no wrong sigstatus is shown */ CloseHandle(CreateThread (NULL, 0, delayed_invalidate_ui, (LPVOID) this, 0, NULL)); commit ef015c7a53fedb004ff0c049add887def231957b Author: Andre Heinecke Date: Mon Jan 8 09:27:57 2018 +0100 Fix memleak in mail object * src/mail.cpp (Mail::~Mail): Free cached body information. diff --git a/src/mail.cpp b/src/mail.cpp index 266a428..e0f988a 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -197,6 +197,8 @@ Mail::~Mail() log_oom_extra ("%s:%s: non crypto mail: %p destroyed", SRCNAME, __func__, this); } + xfree (m_cached_html_body); + xfree (m_cached_plain_body); gpgrt_lock_unlock (&dtor_lock); } ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 8 ++++++-- src/mailitem-events.cpp | 2 ++ src/mapihelp.cpp | 31 ++++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 7 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 8 13:54:05 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 08 Jan 2018 13:54:05 +0100 Subject: [git] gnupg-doc - branch, master, updated. ed7296a3bd46a46352630d772a8b9753083441b2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via ed7296a3bd46a46352630d772a8b9753083441b2 (commit) from f7156272064eb08432fe39280d23f2ac4b0810b5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ed7296a3bd46a46352630d772a8b9753083441b2 Author: Werner Koch Date: Mon Jan 8 13:48:54 2018 +0100 verein: Add Guilhem as new member. diff --git a/web/verein/members.org b/web/verein/members.org index 93c34d7..6ccdc45 100644 --- a/web/verein/members.org +++ b/web/verein/members.org @@ -14,6 +14,7 @@ active in development or in evangelizing end-to-end encryption. - Bernhard Reiter - Damien Goutte-Gattat - Daniel Kahn Gillmor + - Guilhem Moulin - Holger Smolinski - Justus Winter - Kai Michaelis ----------------------------------------------------------------------- Summary of changes: web/verein/members.org | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 9 16:17:56 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 09 Jan 2018 16:17:56 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-8-g08a7a0d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 08a7a0db7169ec6ab0abc2468fdcd16a8e06d4ce (commit) from df029bca0eecd11f78bd0ef95360d0f37cb4b9d5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 08a7a0db7169ec6ab0abc2468fdcd16a8e06d4ce Author: Andre Heinecke Date: Tue Jan 9 16:12:55 2018 +0100 Cache recipients trough oom and add fallbacks * src/mail.cpp (Mail::update_oom_data): Also cache recipients from oom. (Mail::Mail): Initialize cached recipients. (Mail::~Mail): Free cached recipients. (Mail::take_cached_recipients): New. * src/mail.h: Update accordingly. * src/message.cpp (get_recipients): Improve logging. (sign_encrypt): Use cached recipients. * src/oomhelp.cpp (get_oom_object): Tune down error. (get_recipient_addr_fallbacks): New. (get_oom_recipients): Improve with more fallbacks. * src/oomhelp.h (PR_EMS_AB_PROXY_ADDRESSES_DASL): Define. -- This is a blind fix as I can't reproduce scenarios where this is necessary. Probably with exchange address books etc. Adding more fallbacks should not hurt the current uses where it would stop after the first lookup is successful. GnuPG-Bug-Id: T3616 diff --git a/src/mail.cpp b/src/mail.cpp index 114e65c..7f709eb 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -132,6 +132,7 @@ Mail::Mail (LPDISPATCH mailitem) : m_crypto_flags(0), m_cached_html_body(nullptr), m_cached_plain_body(nullptr), + m_cached_recipients(nullptr), m_type(MSGTYPE_UNKNOWN), m_do_inline(false), m_is_gsuite(false) @@ -199,6 +200,9 @@ Mail::~Mail() } xfree (m_cached_html_body); xfree (m_cached_plain_body); + for (int i = 0; m_cached_recipients && m_cached_recipients[i]; ++i) + xfree (m_cached_recipients[i]); + xfree (m_cached_recipients); gpgrt_lock_unlock (&dtor_lock); } @@ -1142,23 +1146,30 @@ Mail::update_oom_data () LPDISPATCH sender = NULL; log_debug ("%s:%s", SRCNAME, __func__); - /* Update the body format. */ - m_is_html_alternative = get_oom_int (m_mailitem, "BodyFormat") > 1; - - /* Store the body. It was not obvious for me (aheinecke) how - to access this through MAPI. */ - if (m_is_html_alternative) + if (!is_crypto_mail()) { - log_debug ("%s:%s: Is html alternative mail.", SRCNAME, __func__); - xfree (m_cached_html_body); - m_cached_html_body = get_oom_string (m_mailitem, "HTMLBody"); + /* Update the body format. */ + m_is_html_alternative = get_oom_int (m_mailitem, "BodyFormat") > 1; + + /* Store the body. It was not obvious for me (aheinecke) how + to access this through MAPI. */ + if (m_is_html_alternative) + { + log_debug ("%s:%s: Is html alternative mail.", SRCNAME, __func__); + xfree (m_cached_html_body); + m_cached_html_body = get_oom_string (m_mailitem, "HTMLBody"); + } + xfree (m_cached_plain_body); + m_cached_plain_body = get_oom_string (m_mailitem, "Body"); + + for (int i = 0; m_cached_recipients && m_cached_recipients[i]; ++i) + xfree (m_cached_recipients[i]); + xfree (m_cached_recipients); + m_cached_recipients = get_recipients (); } - xfree (m_cached_plain_body); - m_cached_plain_body = get_oom_string (m_mailitem, "Body"); /* For some reason outlook may store the recipient address in the send using account field. If we have SMTP we prefer the SenderEmailAddress string. */ - if (is_crypto_mail ()) { /* This is the case where we are reading a mail and not composing. @@ -2394,3 +2405,11 @@ Mail::needs_encrypt() const { return m_needs_encrypt; } + +char ** +Mail::take_cached_recipients() +{ + char **ret = m_cached_recipients; + m_cached_recipients = nullptr; + return ret; +} diff --git a/src/mail.h b/src/mail.h index 28b4bb5..48141b3 100644 --- a/src/mail.h +++ b/src/mail.h @@ -314,6 +314,11 @@ public: */ char *take_cached_plain_body (); + /** Get the cached recipients. It is updated in update_oom_data. + Caller takes ownership of the list and has to free it. + */ + char **take_cached_recipients (); + /** Returns 1 if the mail was encrypted, 2 if signed, 3 if both. Only valid after decrypt_verify. */ @@ -358,6 +363,7 @@ private: std::string m_sender; char *m_cached_html_body; /* Cached html body. */ char *m_cached_plain_body; /* Cached plain body. */ + char **m_cached_recipients; msgtype_t m_type; /* Our messagetype as set in mapi */ std::shared_ptr m_parser; GpgME::VerificationResult m_verify_result; diff --git a/src/message.cpp b/src/message.cpp index 08a38de..8e63c0d 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -32,6 +32,7 @@ #include "display.h" #include "message.h" #include "gpgolstr.h" +#include "mail.h" /* Wrapper around UlRelease with error checking. */ @@ -1040,6 +1041,9 @@ get_recipients (LPMESSAGE message) found_one = true; break; + case PT_ERROR: + log_debug ("%s:%s: proptag=0x%08lx is error", + SRCNAME, __func__, val.ulPropTag); default: log_debug ("%s:%s: proptag=0x%08lx not supported\n", SRCNAME, __func__, val.ulPropTag); @@ -1086,9 +1090,16 @@ sign_encrypt (LPMESSAGE message, protocol_t protocol, HWND hwnd, int signflag, const char *sender, Mail* mail) { gpg_error_t err; - char **recipients; + char **recipients = nullptr; - recipients = get_recipients (message); + if (mail) + { + recipients = mail->take_cached_recipients (); + } + if (!recipients) + { + recipients = get_recipients (message); + } if (!recipients || !recipients[0]) { MessageBox (hwnd, _("No recipients to encrypt to are given"), diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index 2141c9c..45013b4 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -317,7 +317,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname) SysFreeString (parmstr); if (hr != S_OK || vtResult.vt != VT_DISPATCH) { - log_debug ("%s:%s: error: '%s' p=%p vt=%d hr=0x%x argErr=0x%x", + log_debug ("%s:%s: failure: '%s' p=%p vt=%d hr=0x%x argErr=0x%x", SRCNAME, __func__, name, vtResult.pdispVal, vtResult.vt, (unsigned int)hr, (unsigned int)argErr); @@ -329,7 +329,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname) pObj = vtResult.pdispVal; } - log_debug ("%s:%s: error: no object", SRCNAME, __func__); + log_debug ("%s:%s: no object", SRCNAME, __func__); return NULL; } @@ -1072,6 +1072,64 @@ get_pa_int (LPDISPATCH pDisp, const char *property, int *rInt) return 0; } +/* Helper for additional fallbacks in recipient lookup */ +static char * +get_recipient_addr_fallbacks (LPDISPATCH recipient) +{ + LPDISPATCH addr_entry = get_oom_object (recipient, "AddressEntry"); + + if (!addr_entry) + { + log_debug ("%s:%s: Failed to find AddressEntry", + SRCNAME, __func__); + return nullptr; + } + + /* Maybe check for type here? We are pretty sure that we are exchange */ + + /* According to MSDN Message Boards the PR_EMS_AB_PROXY_ADDRESSES_DASL + is more avilable then the SMTP Address. */ + char *ret = get_pa_string (addr_entry, PR_EMS_AB_PROXY_ADDRESSES_DASL); + if (ret) + { + log_debug ("%s:%s: Found recipient through AB_PROXY: %s", + SRCNAME, __func__, ret); + + char *smtpbegin = strstr(ret, "SMTP:"); + if (smtpbegin == ret) + { + ret += 5; + } + gpgol_release (addr_entry); + return ret; + } + else + { + log_debug ("%s:%s: Failed AB_PROXY lookup.", + SRCNAME, __func__); + } + + LPDISPATCH ex_user = get_oom_object (addr_entry, "GetExchangeUser"); + gpgol_release (addr_entry); + if (!ex_user) + { + log_debug ("%s:%s: Failed to find ExchangeUser", + SRCNAME, __func__); + return nullptr; + } + + ret = get_oom_string (ex_user, "PrimarySmtpAddress"); + gpgol_release (ex_user); + if (ret) + { + log_debug ("%s:%s: Found recipient through exchange user primary smtp address: %s", + SRCNAME, __func__, ret); + return ret; + } + + return nullptr; +} + /* Gets a malloced NULL terminated array of recipent strings from an OOM recipients Object. */ char ** @@ -1103,22 +1161,26 @@ get_oom_recipients (LPDISPATCH recipients) SRCNAME, __func__, i); break; } - else + char *resolved = get_pa_string (recipient, PR_SMTP_ADDRESS_DASL); + if (resolved) { - char *address, - *resolved; - address = get_oom_string (recipient, "Address"); - resolved = get_pa_string (recipient, PR_SMTP_ADDRESS_DASL); - if (resolved) - { - xfree (address); - recipientAddrs[i-1] = resolved; - continue; - } - log_debug ("%s:%s: Failed to look up SMTP Address;", - SRCNAME, __func__); - recipientAddrs[i-1] = address; + recipientAddrs[i-1] = resolved; + gpgol_release (recipient); + continue; } + /* No PR_SMTP_ADDRESS first fallback */ + resolved = get_recipient_addr_fallbacks (recipient); + gpgol_release (recipient); + if (resolved) + { + recipientAddrs[i-1] = resolved; + continue; + } + + char *address = get_oom_string (recipient, "Address"); + log_debug ("%s:%s: Failed to look up Address probably EX addr is returned", + SRCNAME, __func__); + recipientAddrs[i-1] = address; } return recipientAddrs; } diff --git a/src/oomhelp.h b/src/oomhelp.h index e719b79..1008860 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -85,6 +85,11 @@ DEFINE_OLEGUID(IID_IOleWindow, 0x00000114, 0, 0); "http://schemas.microsoft.com/mapi/proptag/0x39FE001E" #endif +#ifndef PR_EMS_AB_PROXY_ADDRESSES_DASL +#define PR_EMS_AB_PROXY_ADDRESSES_DASL \ + "http://schemas.microsoft.com/mapi/proptag/0x800F101E" +#endif + #ifndef PR_ATTACHMENT_HIDDEN_DASL #define PR_ATTACHMENT_HIDDEN_DASL \ "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B" ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 43 ++++++++++++++++++-------- src/mail.h | 6 ++++ src/message.cpp | 15 +++++++-- src/oomhelp.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++---------- src/oomhelp.h | 5 +++ 5 files changed, 133 insertions(+), 30 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 9 18:17:26 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Tue, 09 Jan 2018 18:17:26 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-32-ga00c5b2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via a00c5b2988cea256c7823a76ce601febf02c790f (commit) via c9e9cb2eb6a1c659d3825ca627228b732f2f2152 (commit) from b3ec0f752c925cde36f560f0f9309ab6450bbfd9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a00c5b2988cea256c7823a76ce601febf02c790f Author: Jussi Kivilinna Date: Sat Jan 6 18:53:20 2018 +0200 Add AES-NI acceleration for AES-XTS * cipher/cipher-internal.h (gcry_cipher_handle): Change bulk XTS function to take cipher context. * cipher/cipher-xts.c (_gcry_cipher_xts_crypt): Ditto. * cipher/cipher.c (_gcry_cipher_open_internal): Setup AES-NI XTS bulk function. * cipher/rijndael-aesni.c (xts_gfmul_const, _gcry_aes_aesni_xts_enc) (_gcry_aes_aesni_xts_enc, _gcry_aes_aesni_xts_crypt): New. * cipher/rijndael.c (_gcry_aes_aesni_xts_crypt) (_gcry_aes_xts_crypt): New. * src/cipher.h (_gcry_aes_xts_crypt): New. -- Benchmarks on Intel Core i7-4790K, 4.0Ghz (no turbo): Before: XTS enc | 1.66 ns/B 575.7 MiB/s 6.63 c/B XTS dec | 1.66 ns/B 575.5 MiB/s 6.63 c/B After (~6x faster): XTS enc | 0.270 ns/B 3528.5 MiB/s 1.08 c/B XTS dec | 0.272 ns/B 3511.5 MiB/s 1.09 c/B Signed-off-by: Jussi Kivilinna diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index b748125..8c897d7 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -146,7 +146,7 @@ struct gcry_cipher_handle const void *inbuf_arg, size_t nblocks, int encrypt); size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); - void (*xts_crypt)(gcry_cipher_hd_t c, unsigned char *tweak, + void (*xts_crypt)(void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); } bulk; diff --git a/cipher/cipher-xts.c b/cipher/cipher-xts.c index 4da89e5..06cefbe 100644 --- a/cipher/cipher-xts.c +++ b/cipher/cipher-xts.c @@ -93,7 +93,8 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t c, /* Use a bulk method if available. */ if (nblocks && c->bulk.xts_crypt) { - c->bulk.xts_crypt (c, c->u_ctr.ctr, outbuf, inbuf, nblocks, encrypt); + c->bulk.xts_crypt (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks, + encrypt); inbuf += nblocks * GCRY_XTS_BLOCK_LEN; outbuf += nblocks * GCRY_XTS_BLOCK_LEN; inbuflen -= nblocks * GCRY_XTS_BLOCK_LEN; diff --git a/cipher/cipher.c b/cipher/cipher.c index 9812738..063c13d 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -532,6 +532,7 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle, h->bulk.ctr_enc = _gcry_aes_ctr_enc; h->bulk.ocb_crypt = _gcry_aes_ocb_crypt; h->bulk.ocb_auth = _gcry_aes_ocb_auth; + h->bulk.xts_crypt = _gcry_aes_xts_crypt; break; #endif /*USE_AES*/ #ifdef USE_BLOWFISH diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index 3d323cf..50a0745 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -3007,4 +3007,295 @@ _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, } +static const u64 xts_gfmul_const[16] __attribute__ ((aligned (16))) = + { 0x87, 0x01 }; + + +static void +_gcry_aes_aesni_xts_enc (RIJNDAEL_context *ctx, unsigned char *tweak, + unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) +{ + aesni_prepare_2_6_variable; + + aesni_prepare (); + aesni_prepare_2_6 (); + + /* Preload Tweak */ + asm volatile ("movdqu %[tweak], %%xmm5\n\t" + "movdqa %[gfmul], %%xmm6\n\t" + : + : [tweak] "m" (*tweak), + [gfmul] "m" (*xts_gfmul_const) + : "memory" ); + + for ( ;nblocks >= 4; nblocks -= 4 ) + { + asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" + "movdqu %[inbuf0], %%xmm1\n\t" + "pxor %%xmm5, %%xmm1\n\t" + "movdqu %%xmm5, %[outbuf0]\n\t" + + "movdqa %%xmm4, %%xmm0\n\t" + "paddd %%xmm4, %%xmm4\n\t" + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf0] "=m" (*(outbuf + 0 * 16)) + : [inbuf0] "m" (*(inbuf + 0 * 16)) + : "memory" ); + + asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" + "pxor %%xmm5, %%xmm2\n\t" + "movdqu %%xmm5, %[outbuf1]\n\t" + + "movdqa %%xmm4, %%xmm0\n\t" + "paddd %%xmm4, %%xmm4\n\t" + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf1] "=m" (*(outbuf + 1 * 16)) + : [inbuf1] "m" (*(inbuf + 1 * 16)) + : "memory" ); + + asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm5, %%xmm3\n\t" + "movdqu %%xmm5, %[outbuf2]\n\t" + + "movdqa %%xmm4, %%xmm0\n\t" + "paddd %%xmm4, %%xmm4\n\t" + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf2] "=m" (*(outbuf + 2 * 16)) + : [inbuf2] "m" (*(inbuf + 2 * 16)) + : "memory" ); + + asm volatile ("movdqa %%xmm4, %%xmm0\n\t" + "movdqu %[inbuf3], %%xmm4\n\t" + "pxor %%xmm5, %%xmm4\n\t" + "movdqu %%xmm5, %[outbuf3]\n\t" + + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf3] "=m" (*(outbuf + 3 * 16)) + : [inbuf3] "m" (*(inbuf + 3 * 16)) + : "memory" ); + + do_aesni_enc_vec4 (ctx); + + asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" + "movdqu %[outbuf1], %%xmm0\n\t" + "movdqu %%xmm1, %[outbuf0]\n\t" + "movdqu %[outbuf2], %%xmm1\n\t" + "pxor %%xmm0, %%xmm2\n\t" + "movdqu %[outbuf3], %%xmm0\n\t" + "pxor %%xmm1, %%xmm3\n\t" + "pxor %%xmm0, %%xmm4\n\t" + "movdqu %%xmm2, %[outbuf1]\n\t" + "movdqu %%xmm3, %[outbuf2]\n\t" + "movdqu %%xmm4, %[outbuf3]\n\t" + : [outbuf0] "+m" (*(outbuf + 0 * 16)), + [outbuf1] "+m" (*(outbuf + 1 * 16)), + [outbuf2] "+m" (*(outbuf + 2 * 16)), + [outbuf3] "+m" (*(outbuf + 3 * 16)) + : + : "memory" ); + + outbuf += BLOCKSIZE * 4; + inbuf += BLOCKSIZE * 4; + } + + for ( ;nblocks; nblocks-- ) + { + asm volatile ("movdqu %[inbuf], %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "movdqa %%xmm5, %%xmm4\n\t" + + "pshufd $0x13, %%xmm5, %%xmm1\n\t" + "psrad $31, %%xmm1\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm1\n\t" + "pxor %%xmm1, %%xmm5\n\t" + : + : [inbuf] "m" (*inbuf) + : "memory" ); + + do_aesni_enc (ctx); + + asm volatile ("pxor %%xmm4, %%xmm0\n\t" + "movdqu %%xmm0, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : + : "memory" ); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile ("movdqu %%xmm5, %[tweak]\n\t" + : [tweak] "=m" (*tweak) + : + : "memory" ); + + aesni_cleanup (); + aesni_cleanup_2_6 (); +} + + +static void +_gcry_aes_aesni_xts_dec (RIJNDAEL_context *ctx, unsigned char *tweak, + unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) +{ + aesni_prepare_2_6_variable; + + aesni_prepare (); + aesni_prepare_2_6 (); + + /* Preload Tweak */ + asm volatile ("movdqu %[tweak], %%xmm5\n\t" + "movdqa %[gfmul], %%xmm6\n\t" + : + : [tweak] "m" (*tweak), + [gfmul] "m" (*xts_gfmul_const) + : "memory" ); + + for ( ;nblocks >= 4; nblocks -= 4 ) + { + asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" + "movdqu %[inbuf0], %%xmm1\n\t" + "pxor %%xmm5, %%xmm1\n\t" + "movdqu %%xmm5, %[outbuf0]\n\t" + + "movdqa %%xmm4, %%xmm0\n\t" + "paddd %%xmm4, %%xmm4\n\t" + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf0] "=m" (*(outbuf + 0 * 16)) + : [inbuf0] "m" (*(inbuf + 0 * 16)) + : "memory" ); + + asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" + "pxor %%xmm5, %%xmm2\n\t" + "movdqu %%xmm5, %[outbuf1]\n\t" + + "movdqa %%xmm4, %%xmm0\n\t" + "paddd %%xmm4, %%xmm4\n\t" + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf1] "=m" (*(outbuf + 1 * 16)) + : [inbuf1] "m" (*(inbuf + 1 * 16)) + : "memory" ); + + asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm5, %%xmm3\n\t" + "movdqu %%xmm5, %[outbuf2]\n\t" + + "movdqa %%xmm4, %%xmm0\n\t" + "paddd %%xmm4, %%xmm4\n\t" + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf2] "=m" (*(outbuf + 2 * 16)) + : [inbuf2] "m" (*(inbuf + 2 * 16)) + : "memory" ); + + asm volatile ("movdqa %%xmm4, %%xmm0\n\t" + "movdqu %[inbuf3], %%xmm4\n\t" + "pxor %%xmm5, %%xmm4\n\t" + "movdqu %%xmm5, %[outbuf3]\n\t" + + "psrad $31, %%xmm0\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm5\n\t" + : [outbuf3] "=m" (*(outbuf + 3 * 16)) + : [inbuf3] "m" (*(inbuf + 3 * 16)) + : "memory" ); + + do_aesni_dec_vec4 (ctx); + + asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" + "movdqu %[outbuf1], %%xmm0\n\t" + "movdqu %%xmm1, %[outbuf0]\n\t" + "movdqu %[outbuf2], %%xmm1\n\t" + "pxor %%xmm0, %%xmm2\n\t" + "movdqu %[outbuf3], %%xmm0\n\t" + "pxor %%xmm1, %%xmm3\n\t" + "pxor %%xmm0, %%xmm4\n\t" + "movdqu %%xmm2, %[outbuf1]\n\t" + "movdqu %%xmm3, %[outbuf2]\n\t" + "movdqu %%xmm4, %[outbuf3]\n\t" + : [outbuf0] "+m" (*(outbuf + 0 * 16)), + [outbuf1] "+m" (*(outbuf + 1 * 16)), + [outbuf2] "+m" (*(outbuf + 2 * 16)), + [outbuf3] "+m" (*(outbuf + 3 * 16)) + : + : "memory" ); + + outbuf += BLOCKSIZE * 4; + inbuf += BLOCKSIZE * 4; + } + + for ( ;nblocks; nblocks-- ) + { + asm volatile ("movdqu %[inbuf], %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "movdqa %%xmm5, %%xmm4\n\t" + + "pshufd $0x13, %%xmm5, %%xmm1\n\t" + "psrad $31, %%xmm1\n\t" + "paddq %%xmm5, %%xmm5\n\t" + "pand %%xmm6, %%xmm1\n\t" + "pxor %%xmm1, %%xmm5\n\t" + : + : [inbuf] "m" (*inbuf) + : "memory" ); + + do_aesni_dec (ctx); + + asm volatile ("pxor %%xmm4, %%xmm0\n\t" + "movdqu %%xmm0, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : + : "memory" ); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile ("movdqu %%xmm5, %[tweak]\n\t" + : [tweak] "=m" (*tweak) + : + : "memory" ); + + aesni_cleanup (); + aesni_cleanup_2_6 (); +} + + +void +_gcry_aes_aesni_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, + unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks, int encrypt) +{ + if (encrypt) + _gcry_aes_aesni_xts_enc(ctx, tweak, outbuf, inbuf, nblocks); + else + _gcry_aes_aesni_xts_dec(ctx, tweak, outbuf, inbuf, nblocks); +} + #endif /* USE_AESNI */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 8637195..548bfa0 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -103,6 +103,11 @@ extern void _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, int encrypt); extern void _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); +extern void _gcry_aes_aesni_xts_crypt (RIJNDAEL_context *ctx, + unsigned char *tweak, + unsigned char *outbuf, + const unsigned char *inbuf, + size_t nblocks, int encrypt); #endif #ifdef USE_SSSE3 @@ -1467,6 +1472,85 @@ _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) } +/* Bulk encryption/decryption of complete blocks in XTS mode. */ +void +_gcry_aes_xts_crypt (void *context, unsigned char *tweak, + void *outbuf_arg, const void *inbuf_arg, + size_t nblocks, int encrypt) +{ + RIJNDAEL_context *ctx = context; + unsigned char *outbuf = outbuf_arg; + const unsigned char *inbuf = inbuf_arg; + unsigned int burn_depth = 0; + rijndael_cryptfn_t crypt_fn; + u64 tweak_lo, tweak_hi, tweak_next_lo, tweak_next_hi, tmp_lo, tmp_hi, carry; + + if (encrypt) + { + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + + crypt_fn = ctx->encrypt_fn; + } + else + { + check_decryption_preparation (ctx); + + if (ctx->prefetch_dec_fn) + ctx->prefetch_dec_fn(); + + crypt_fn = ctx->decrypt_fn; + } + + if (0) + ; +#ifdef USE_AESNI + else if (ctx->use_aesni) + { + _gcry_aes_aesni_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); + burn_depth = 0; + } +#endif /*USE_AESNI*/ + else + { + tweak_next_lo = buf_get_le64 (tweak + 0); + tweak_next_hi = buf_get_le64 (tweak + 8); + + while (nblocks) + { + tweak_lo = tweak_next_lo; + tweak_hi = tweak_next_hi; + + /* Xor-Encrypt/Decrypt-Xor block. */ + tmp_lo = buf_get_le64 (inbuf + 0) ^ tweak_lo; + tmp_hi = buf_get_le64 (inbuf + 8) ^ tweak_hi; + + buf_put_le64 (outbuf + 0, tmp_lo); + buf_put_le64 (outbuf + 8, tmp_hi); + + /* Generate next tweak. */ + carry = -(tweak_next_hi >> 63) & 0x87; + tweak_next_hi = (tweak_next_hi << 1) + (tweak_next_lo >> 63); + tweak_next_lo = (tweak_next_lo << 1) ^ carry; + + burn_depth = crypt_fn (ctx, outbuf, outbuf); + + buf_put_le64 (outbuf + 0, buf_get_le64 (outbuf + 0) ^ tweak_lo); + buf_put_le64 (outbuf + 8, buf_get_le64 (outbuf + 8) ^ tweak_hi); + + outbuf += GCRY_XTS_BLOCK_LEN; + inbuf += GCRY_XTS_BLOCK_LEN; + nblocks--; + } + + buf_put_le64 (tweak + 0, tweak_next_lo); + buf_put_le64 (tweak + 8, tweak_next_hi); + } + + if (burn_depth) + _gcry_burn_stack (burn_depth + 5 * sizeof(void *)); +} + /* Run the self-tests for AES 128. Returns NULL on success. */ static const char* diff --git a/src/cipher.h b/src/cipher.h index a6f257d..7c2e5d9 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -164,6 +164,9 @@ size_t _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); size_t _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); +void _gcry_aes_xts_crypt (void *context, unsigned char *tweak, + void *outbuf_arg, const void *inbuf_arg, + size_t nblocks, int encrypt); /*-- blowfish.c --*/ void _gcry_blowfish_cfb_dec (void *context, unsigned char *iv, commit c9e9cb2eb6a1c659d3825ca627228b732f2f2152 Author: Jussi Kivilinna Date: Sat Jan 6 18:53:20 2018 +0200 AES-NI improvements for AMD64 * cipher/rijndael-aesni.c [__x86_64__] (aesni_prepare_7_15_variable) (aesni_prepare_7_15, aesni_cleanup_7_15, do_aesni_enc_vec8) (do_aesni_dec_vec8, do_aesni_ctr_8): New. (_gcry_aes_aesni_ctr_enc, _gcry_aes_aesni_cfb_dec) (_gcry_aes_aesni_cbc_dec, aesni_ocb_enc, aesni_ocb_dec) (_gcry_aes_aesni_ocb_auth) [__x86_64__]: Add 8 parallel blocks processing. -- Benchmarks on Intel Core i7-4790K, 4.0Ghz (no turbo, no HT): Before: AES | nanosecs/byte mebibytes/sec cycles/byte CBC dec | 0.175 ns/B 5448.7 MiB/s 0.700 c/B CFB dec | 0.174 ns/B 5466.2 MiB/s 0.698 c/B CTR enc | 0.182 ns/B 5226.0 MiB/s 0.730 c/B OCB enc | 0.194 ns/B 4913.9 MiB/s 0.776 c/B OCB dec | 0.200 ns/B 4769.2 MiB/s 0.800 c/B OCB auth | 0.172 ns/B 5545.0 MiB/s 0.688 c/B After (1.08x to 1.14x faster): AES | nanosecs/byte mebibytes/sec cycles/byte CBC dec | 0.157 ns/B 6075.6 MiB/s 0.628 c/B CFB dec | 0.158 ns/B 6034.1 MiB/s 0.632 c/B CTR enc | 0.159 ns/B 5979.4 MiB/s 0.638 c/B OCB enc | 0.175 ns/B 5447.1 MiB/s 0.700 c/B OCB dec | 0.183 ns/B 5203.9 MiB/s 0.733 c/B OCB auth | 0.156 ns/B 6101.3 MiB/s 0.625 c/B Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index 735e5cd..3d323cf 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -55,6 +55,7 @@ typedef struct u128_s #ifdef __WIN64__ /* XMM6-XMM15 are callee-saved registers on WIN64. */ # define aesni_prepare_2_6_variable char win64tmp[16] +# define aesni_prepare_7_15_variable char win64tmp7_15[16 * 9] # define aesni_prepare() do { } while (0) # define aesni_prepare_2_6() \ do { asm volatile ("movdqu %%xmm6, %0\n\t" \ @@ -62,6 +63,20 @@ typedef struct u128_s : \ : "memory"); \ } while (0) +# define aesni_prepare_7_15() \ + do { asm volatile ("movdqu %%xmm7, 0*16(%0)\n\t" \ + "movdqu %%xmm8, 1*16(%0)\n\t" \ + "movdqu %%xmm9, 2*16(%0)\n\t" \ + "movdqu %%xmm10, 3*16(%0)\n\t" \ + "movdqu %%xmm11, 4*16(%0)\n\t" \ + "movdqu %%xmm12, 5*16(%0)\n\t" \ + "movdqu %%xmm13, 6*16(%0)\n\t" \ + "movdqu %%xmm14, 7*16(%0)\n\t" \ + "movdqu %%xmm15, 8*16(%0)\n\t" \ + : \ + : "r" (win64tmp7_15) \ + : "memory"); \ + } while (0) # define aesni_cleanup() \ do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ "pxor %%xmm1, %%xmm1\n" :: ); \ @@ -76,6 +91,20 @@ typedef struct u128_s : "m" (*win64tmp) \ : "memory"); \ } while (0) +# define aesni_cleanup_7_15() \ + do { asm volatile ("movdqu 0*16(%0), %%xmm7\n\t" \ + "movdqu 1*16(%0), %%xmm8\n\t" \ + "movdqu 2*16(%0), %%xmm9\n\t" \ + "movdqu 3*16(%0), %%xmm10\n\t" \ + "movdqu 4*16(%0), %%xmm11\n\t" \ + "movdqu 5*16(%0), %%xmm12\n\t" \ + "movdqu 6*16(%0), %%xmm13\n\t" \ + "movdqu 7*16(%0), %%xmm14\n\t" \ + "movdqu 8*16(%0), %%xmm15\n\t" \ + : \ + : "r" (win64tmp7_15) \ + : "memory"); \ + } while (0) #else # define aesni_prepare_2_6_variable # define aesni_prepare() do { } while (0) @@ -91,6 +120,21 @@ typedef struct u128_s "pxor %%xmm5, %%xmm5\n" \ "pxor %%xmm6, %%xmm6\n":: ); \ } while (0) +# ifdef __x86_64__ +# define aesni_prepare_7_15_variable +# define aesni_prepare_7_15() do { } while (0) +# define aesni_cleanup_7_15() \ + do { asm volatile ("pxor %%xmm7, %%xmm7\n\t" \ + "pxor %%xmm8, %%xmm8\n" \ + "pxor %%xmm9, %%xmm9\n" \ + "pxor %%xmm10, %%xmm10\n" \ + "pxor %%xmm11, %%xmm11\n" \ + "pxor %%xmm12, %%xmm12\n" \ + "pxor %%xmm13, %%xmm13\n" \ + "pxor %%xmm14, %%xmm14\n" \ + "pxor %%xmm15, %%xmm15\n":: ); \ + } while (0) +# endif #endif void @@ -704,6 +748,314 @@ do_aesni_dec_vec4 (const RIJNDAEL_context *ctx) } +#ifdef __x86_64__ + +/* Encrypt eight blocks using the Intel AES-NI instructions. Blocks are input + * and output through SSE registers xmm1 to xmm4 and xmm8 to xmm11. */ +static inline void +do_aesni_enc_vec8 (const RIJNDAEL_context *ctx) +{ + asm volatile ("movdqa (%[key]), %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ + "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ + "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ + "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ + "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ + "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ + "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ + "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ + "movdqa 0x10(%[key]), %%xmm0\n\t" + "cmpl $12, %[rounds]\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x20(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x30(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x40(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x50(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x60(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x70(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x80(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0x90(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0xa0(%[key]), %%xmm0\n\t" + "jb .Ldeclast%=\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0xb0(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0xc0(%[key]), %%xmm0\n\t" + "je .Ldeclast%=\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0xd0(%[key]), %%xmm0\n\t" + "aesenc %%xmm0, %%xmm1\n\t" + "aesenc %%xmm0, %%xmm2\n\t" + "aesenc %%xmm0, %%xmm3\n\t" + "aesenc %%xmm0, %%xmm4\n\t" + "aesenc %%xmm0, %%xmm8\n\t" + "aesenc %%xmm0, %%xmm9\n\t" + "aesenc %%xmm0, %%xmm10\n\t" + "aesenc %%xmm0, %%xmm11\n\t" + "movdqa 0xe0(%[key]), %%xmm0\n" + + ".Ldeclast%=:\n\t" + "aesenclast %%xmm0, %%xmm1\n\t" + "aesenclast %%xmm0, %%xmm2\n\t" + "aesenclast %%xmm0, %%xmm3\n\t" + "aesenclast %%xmm0, %%xmm4\n\t" + "aesenclast %%xmm0, %%xmm8\n\t" + "aesenclast %%xmm0, %%xmm9\n\t" + "aesenclast %%xmm0, %%xmm10\n\t" + "aesenclast %%xmm0, %%xmm11\n\t" + : /* no output */ + : [key] "r" (ctx->keyschenc), + [rounds] "r" (ctx->rounds) + : "cc", "memory"); +} + + +/* Decrypt eight blocks using the Intel AES-NI instructions. Blocks are input + * and output through SSE registers xmm1 to xmm4 and xmm8 to xmm11. */ +static inline void +do_aesni_dec_vec8 (const RIJNDAEL_context *ctx) +{ + asm volatile ("movdqa (%[key]), %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ + "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ + "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ + "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ + "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ + "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ + "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ + "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ + "movdqa 0x10(%[key]), %%xmm0\n\t" + "cmpl $12, %[rounds]\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x20(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x30(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x40(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x50(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x60(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x70(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x80(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0x90(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0xa0(%[key]), %%xmm0\n\t" + "jb .Ldeclast%=\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0xb0(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0xc0(%[key]), %%xmm0\n\t" + "je .Ldeclast%=\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0xd0(%[key]), %%xmm0\n\t" + "aesdec %%xmm0, %%xmm1\n\t" + "aesdec %%xmm0, %%xmm2\n\t" + "aesdec %%xmm0, %%xmm3\n\t" + "aesdec %%xmm0, %%xmm4\n\t" + "aesdec %%xmm0, %%xmm8\n\t" + "aesdec %%xmm0, %%xmm9\n\t" + "aesdec %%xmm0, %%xmm10\n\t" + "aesdec %%xmm0, %%xmm11\n\t" + "movdqa 0xe0(%[key]), %%xmm0\n" + + ".Ldeclast%=:\n\t" + "aesdeclast %%xmm0, %%xmm1\n\t" + "aesdeclast %%xmm0, %%xmm2\n\t" + "aesdeclast %%xmm0, %%xmm3\n\t" + "aesdeclast %%xmm0, %%xmm4\n\t" + "aesdeclast %%xmm0, %%xmm8\n\t" + "aesdeclast %%xmm0, %%xmm9\n\t" + "aesdeclast %%xmm0, %%xmm10\n\t" + "aesdeclast %%xmm0, %%xmm11\n\t" + : /* no output */ + : [key] "r" (ctx->keyschdec), + [rounds] "r" (ctx->rounds) + : "cc", "memory"); +} + +#endif /* __x86_64__ */ + + /* Perform a CTR encryption round using the counter CTR and the input block A. Write the result to the output block B and update CTR. CTR needs to be a 16 byte aligned little-endian value. */ @@ -808,7 +1160,7 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, #define aesenclast_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t" /* Register usage: - esi keyschedule + [key] keyschedule xmm0 CTR-0 xmm1 temp / round key xmm2 CTR-1 @@ -1003,6 +1355,327 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, } +#ifdef __x86_64__ + +/* Eight blocks at a time variant of do_aesni_ctr. */ +static void +do_aesni_ctr_8 (const RIJNDAEL_context *ctx, + unsigned char *ctr, unsigned char *b, const unsigned char *a) +{ + static const byte bige_addb_const[8][16] __attribute__ ((aligned (16))) = + { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 } + }; + const void *bige_addb = bige_addb_const; + + /* Register usage: + [key] keyschedule + xmm0 CTR-0 + xmm1 temp / round key + xmm2 CTR-1 + xmm3 CTR-2 + xmm4 CTR-3 + xmm5 copy of *ctr + xmm6 endian swapping mask + xmm8 CTR-4 + xmm9 CTR-5 + xmm10 CTR-6 + xmm11 CTR-7 + xmm12 temp + xmm13 temp + xmm14 temp + xmm15 temp + */ + + asm volatile (/* detect if 8-bit carry handling is needed */ + "cmpb $0xf7, 15(%[ctr])\n\t" + "ja .Ladd32bit%=\n\t" + + "movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ + "movdqa 0*16(%[addb]), %%xmm2\n\t" /* xmm2 := be(1) */ + "movdqa 1*16(%[addb]), %%xmm3\n\t" /* xmm3 := be(2) */ + "movdqa 2*16(%[addb]), %%xmm4\n\t" /* xmm4 := be(3) */ + "movdqa 3*16(%[addb]), %%xmm8\n\t" /* xmm8 := be(4) */ + "movdqa 4*16(%[addb]), %%xmm9\n\t" /* xmm9 := be(5) */ + "movdqa 5*16(%[addb]), %%xmm10\n\t" /* xmm10 := be(6) */ + "movdqa 6*16(%[addb]), %%xmm11\n\t" /* xmm11 := be(7) */ + "movdqa 7*16(%[addb]), %%xmm5\n\t" /* xmm5 := be(8) */ + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ + "paddb %%xmm0, %%xmm2\n\t" /* xmm2 := be(1) + CTR (xmm0) */ + "paddb %%xmm0, %%xmm3\n\t" /* xmm3 := be(2) + CTR (xmm0) */ + "paddb %%xmm0, %%xmm4\n\t" /* xmm4 := be(3) + CTR (xmm0) */ + "paddb %%xmm0, %%xmm8\n\t" /* xmm8 := be(4) + CTR (xmm0) */ + "paddb %%xmm0, %%xmm9\n\t" /* xmm9 := be(5) + CTR (xmm0) */ + "paddb %%xmm0, %%xmm10\n\t" /* xmm10 := be(6) + CTR (xmm0) */ + "paddb %%xmm0, %%xmm11\n\t" /* xmm11 := be(7) + CTR (xmm0) */ + "paddb %%xmm0, %%xmm5\n\t" /* xmm5 := be(8) + CTR (xmm0) */ + "jmp .Lstore_ctr%=\n\t" + + ".Ladd32bit%=:\n\t" + "movdqa %%xmm5, %%xmm0\n\t" /* xmm0, xmm2 := CTR (xmm5) */ + "movdqa %%xmm0, %%xmm2\n\t" + "pcmpeqd %%xmm1, %%xmm1\n\t" + "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ + + "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := le(xmm2) */ + "psubq %%xmm1, %%xmm2\n\t" /* xmm2++ */ + "movdqa %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ + "psubq %%xmm1, %%xmm3\n\t" /* xmm3++ */ + "movdqa %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */ + "psubq %%xmm1, %%xmm4\n\t" /* xmm4++ */ + "movdqa %%xmm4, %%xmm8\n\t" /* xmm8 := xmm4 */ + "psubq %%xmm1, %%xmm8\n\t" /* xmm8++ */ + "movdqa %%xmm8, %%xmm9\n\t" /* xmm9 := xmm8 */ + "psubq %%xmm1, %%xmm9\n\t" /* xmm9++ */ + "movdqa %%xmm9, %%xmm10\n\t" /* xmm10 := xmm9 */ + "psubq %%xmm1, %%xmm10\n\t" /* xmm10++ */ + "movdqa %%xmm10, %%xmm11\n\t" /* xmm11 := xmm10 */ + "psubq %%xmm1, %%xmm11\n\t" /* xmm11++ */ + "movdqa %%xmm11, %%xmm5\n\t" /* xmm5 := xmm11 */ + "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ */ + + /* detect if 64-bit carry handling is needed */ + "cmpl $0xffffffff, 8(%[ctr])\n\t" + "jne .Lno_carry%=\n\t" + "movl 12(%[ctr]), %%esi\n\t" + "bswapl %%esi\n\t" + "cmpl $0xfffffff8, %%esi\n\t" + "jb .Lno_carry%=\n\t" /* no carry */ + + "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ + "je .Lcarry_xmm5%=\n\t" /* esi == 0xfffffff8 */ + "cmpl $0xfffffffa, %%esi\n\t" + "jb .Lcarry_xmm11%=\n\t" /* esi == 0xfffffff9 */ + "je .Lcarry_xmm10%=\n\t" /* esi == 0xfffffffa */ + "cmpl $0xfffffffc, %%esi\n\t" + "jb .Lcarry_xmm9%=\n\t" /* esi == 0xfffffffb */ + "je .Lcarry_xmm8%=\n\t" /* esi == 0xfffffffc */ + "cmpl $0xfffffffe, %%esi\n\t" + "jb .Lcarry_xmm4%=\n\t" /* esi == 0xfffffffd */ + "je .Lcarry_xmm3%=\n\t" /* esi == 0xfffffffe */ + /* esi == 0xffffffff */ + + "psubq %%xmm1, %%xmm2\n\t" + ".Lcarry_xmm3%=:\n\t" + "psubq %%xmm1, %%xmm3\n\t" + ".Lcarry_xmm4%=:\n\t" + "psubq %%xmm1, %%xmm4\n\t" + ".Lcarry_xmm8%=:\n\t" + "psubq %%xmm1, %%xmm8\n\t" + ".Lcarry_xmm9%=:\n\t" + "psubq %%xmm1, %%xmm9\n\t" + ".Lcarry_xmm10%=:\n\t" + "psubq %%xmm1, %%xmm10\n\t" + ".Lcarry_xmm11%=:\n\t" + "psubq %%xmm1, %%xmm11\n\t" + ".Lcarry_xmm5%=:\n\t" + "psubq %%xmm1, %%xmm5\n\t" + + ".Lno_carry%=:\n\t" + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ + + "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := be(xmm2) */ + "pshufb %%xmm6, %%xmm3\n\t" /* xmm3 := be(xmm3) */ + "pshufb %%xmm6, %%xmm4\n\t" /* xmm4 := be(xmm4) */ + "pshufb %%xmm6, %%xmm5\n\t" /* xmm5 := be(xmm5) */ + "pshufb %%xmm6, %%xmm8\n\t" /* xmm8 := be(xmm8) */ + "pshufb %%xmm6, %%xmm9\n\t" /* xmm9 := be(xmm9) */ + "pshufb %%xmm6, %%xmm10\n\t" /* xmm10 := be(xmm10) */ + "pshufb %%xmm6, %%xmm11\n\t" /* xmm11 := be(xmm11) */ + + ".Lstore_ctr%=:\n\t" + "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ + : + : [ctr] "r" (ctr), + [key] "r" (ctx->keyschenc), + [addb] "r" (bige_addb) + : "%esi", "cc", "memory"); + + asm volatile ("pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ + "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ + "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ + "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ + "pxor %%xmm1, %%xmm8\n\t" /* xmm8 ^= key[0] */ + "pxor %%xmm1, %%xmm9\n\t" /* xmm9 ^= key[0] */ + "pxor %%xmm1, %%xmm10\n\t" /* xmm10 ^= key[0] */ + "pxor %%xmm1, %%xmm11\n\t" /* xmm11 ^= key[0] */ + "movdqa 0x10(%[key]), %%xmm1\n\t" + "cmpl $12, %[rounds]\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x20(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x30(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x40(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x50(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x60(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x70(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x80(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0x90(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0xa0(%[key]), %%xmm1\n\t" + "jb .Lenclast%=\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0xb0(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0xc0(%[key]), %%xmm1\n\t" + "je .Lenclast%=\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0xd0(%[key]), %%xmm1\n\t" + "aesenc %%xmm1, %%xmm0\n\t" + "aesenc %%xmm1, %%xmm2\n\t" + "aesenc %%xmm1, %%xmm3\n\t" + "aesenc %%xmm1, %%xmm4\n\t" + "aesenc %%xmm1, %%xmm8\n\t" + "aesenc %%xmm1, %%xmm9\n\t" + "aesenc %%xmm1, %%xmm10\n\t" + "aesenc %%xmm1, %%xmm11\n\t" + "movdqa 0xe0(%[key]), %%xmm1\n" + + ".Lenclast%=:\n\t" + "aesenclast %%xmm1, %%xmm0\n\t" + "aesenclast %%xmm1, %%xmm2\n\t" + "aesenclast %%xmm1, %%xmm3\n\t" + "aesenclast %%xmm1, %%xmm4\n\t" + "aesenclast %%xmm1, %%xmm8\n\t" + "aesenclast %%xmm1, %%xmm9\n\t" + "aesenclast %%xmm1, %%xmm10\n\t" + "aesenclast %%xmm1, %%xmm11\n\t" + : + : [key] "r" (ctx->keyschenc), + [rounds] "r" (ctx->rounds) + : "cc", "memory"); + + asm volatile ("movdqu 0*16(%[src]), %%xmm12\n\t" /* Get block 1. */ + "movdqu 1*16(%[src]), %%xmm13\n\t" /* Get block 2. */ + "movdqu 2*16(%[src]), %%xmm14\n\t" /* Get block 3. */ + "movdqu 3*16(%[src]), %%xmm15\n\t" /* Get block 4. */ + "movdqu 4*16(%[src]), %%xmm1\n\t" /* Get block 5. */ + "pxor %%xmm12, %%xmm0\n\t" /* EncCTR-1 ^= input */ + "movdqu 5*16(%[src]), %%xmm12\n\t" /* Get block 6. */ + "pxor %%xmm13, %%xmm2\n\t" /* EncCTR-2 ^= input */ + "movdqu 6*16(%[src]), %%xmm13\n\t" /* Get block 7. */ + "pxor %%xmm14, %%xmm3\n\t" /* EncCTR-3 ^= input */ + "movdqu 7*16(%[src]), %%xmm14\n\t" /* Get block 8. */ + "pxor %%xmm15, %%xmm4\n\t" /* EncCTR-4 ^= input */ + "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ + "pxor %%xmm1, %%xmm8\n\t" /* EncCTR-5 ^= input */ + "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ + "pxor %%xmm12, %%xmm9\n\t" /* EncCTR-6 ^= input */ + "movdqu %%xmm2, 1*16(%[dst])\n\t" /* Store block 2. */ + "pxor %%xmm13, %%xmm10\n\t" /* EncCTR-7 ^= input */ + "movdqu %%xmm3, 2*16(%[dst])\n\t" /* Store block 3. */ + "pxor %%xmm14, %%xmm11\n\t" /* EncCTR-8 ^= input */ + "movdqu %%xmm4, 3*16(%[dst])\n\t" /* Store block 4. */ + "movdqu %%xmm8, 4*16(%[dst])\n\t" /* Store block 8. */ + "movdqu %%xmm9, 5*16(%[dst])\n\t" /* Store block 9. */ + "movdqu %%xmm10, 6*16(%[dst])\n\t" /* Store block 10. */ + "movdqu %%xmm11, 7*16(%[dst])\n\t" /* Store block 11. */ + : + : [src] "r" (a), + [dst] "r" (b) + : "memory"); +} + +#endif /* __x86_64__ */ + + unsigned int _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) @@ -1123,7 +1796,25 @@ _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, [ctr] "m" (*ctr) : "memory"); - for ( ;nblocks > 3 ; nblocks -= 4 ) +#ifdef __x86_64__ + if (nblocks >= 8) + { + aesni_prepare_7_15_variable; + + aesni_prepare_7_15(); + + for ( ;nblocks >= 8 ; nblocks -= 8 ) + { + do_aesni_ctr_8 (ctx, ctr, outbuf, inbuf); + outbuf += 8*BLOCKSIZE; + inbuf += 8*BLOCKSIZE; + } + + aesni_cleanup_7_15(); + } +#endif + + for ( ;nblocks >= 4 ; nblocks -= 4 ) { do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf); outbuf += 4*BLOCKSIZE; @@ -1175,6 +1866,76 @@ _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, : "memory" ); /* CFB decryption can be parallelized */ + +#ifdef __x86_64__ + if (nblocks >= 8) + { + aesni_prepare_7_15_variable; + + aesni_prepare_7_15(); + + for ( ;nblocks >= 8; nblocks -= 8) + { + asm volatile + ("movdqu %%xmm6, %%xmm1\n\t" /* load input blocks */ + "movdqu 0*16(%[inbuf]), %%xmm2\n\t" + "movdqu 1*16(%[inbuf]), %%xmm3\n\t" + "movdqu 2*16(%[inbuf]), %%xmm4\n\t" + "movdqu 3*16(%[inbuf]), %%xmm8\n\t" + "movdqu 4*16(%[inbuf]), %%xmm9\n\t" + "movdqu 5*16(%[inbuf]), %%xmm10\n\t" + "movdqu 6*16(%[inbuf]), %%xmm11\n\t" + + "movdqu 7*16(%[inbuf]), %%xmm6\n\t" /* update IV */ + + "movdqa %%xmm2, %%xmm12\n\t" + "movdqa %%xmm3, %%xmm13\n\t" + "movdqa %%xmm4, %%xmm14\n\t" + "movdqa %%xmm8, %%xmm15\n\t" + : /* No output */ + : [inbuf] "r" (inbuf) + : "memory"); + + do_aesni_enc_vec8 (ctx); + + asm volatile + ( + "pxor %%xmm12, %%xmm1\n\t" + "movdqu 4*16(%[inbuf]), %%xmm12\n\t" + "pxor %%xmm13, %%xmm2\n\t" + "movdqu 5*16(%[inbuf]), %%xmm13\n\t" + "pxor %%xmm14, %%xmm3\n\t" + "movdqu 6*16(%[inbuf]), %%xmm14\n\t" + "pxor %%xmm15, %%xmm4\n\t" + "movdqu 7*16(%[inbuf]), %%xmm15\n\t" + + "pxor %%xmm12, %%xmm8\n\t" + "movdqu %%xmm1, 0*16(%[outbuf])\n\t" + "pxor %%xmm13, %%xmm9\n\t" + "movdqu %%xmm2, 1*16(%[outbuf])\n\t" + "pxor %%xmm14, %%xmm10\n\t" + "movdqu %%xmm3, 2*16(%[outbuf])\n\t" + "pxor %%xmm15, %%xmm11\n\t" + "movdqu %%xmm4, 3*16(%[outbuf])\n\t" + + "movdqu %%xmm8, 4*16(%[outbuf])\n\t" + "movdqu %%xmm9, 5*16(%[outbuf])\n\t" + "movdqu %%xmm10, 6*16(%[outbuf])\n\t" + "movdqu %%xmm11, 7*16(%[outbuf])\n\t" + + : /* No output */ + : [inbuf] "r" (inbuf), + [outbuf] "r" (outbuf) + : "memory"); + + outbuf += 8*BLOCKSIZE; + inbuf += 8*BLOCKSIZE; + } + + aesni_cleanup_7_15(); + } +#endif + for ( ;nblocks >= 4; nblocks -= 4) { asm volatile @@ -1260,7 +2021,76 @@ _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, : [iv] "m" (*iv) : "memory"); - for ( ;nblocks > 3 ; nblocks -= 4 ) +#ifdef __x86_64__ + if (nblocks >= 8) + { + aesni_prepare_7_15_variable; + + aesni_prepare_7_15(); + + for ( ;nblocks >= 8 ; nblocks -= 8 ) + { + asm volatile + ("movdqu 0*16(%[inbuf]), %%xmm1\n\t" /* load input blocks */ + "movdqu 1*16(%[inbuf]), %%xmm2\n\t" + "movdqu 2*16(%[inbuf]), %%xmm3\n\t" + "movdqu 3*16(%[inbuf]), %%xmm4\n\t" + "movdqu 4*16(%[inbuf]), %%xmm8\n\t" + "movdqu 5*16(%[inbuf]), %%xmm9\n\t" + "movdqu 6*16(%[inbuf]), %%xmm10\n\t" + "movdqu 7*16(%[inbuf]), %%xmm11\n\t" + + "movdqa %%xmm1, %%xmm12\n\t" + "movdqa %%xmm2, %%xmm13\n\t" + "movdqa %%xmm3, %%xmm14\n\t" + "movdqa %%xmm4, %%xmm15\n\t" + + : /* No output */ + : [inbuf] "r" (inbuf) + : "memory"); + + do_aesni_dec_vec8 (ctx); + + asm volatile + ("pxor %%xmm5, %%xmm1\n\t" /* xor IV with output */ + + "pxor %%xmm12, %%xmm2\n\t" /* xor IV with output */ + "movdqu 4*16(%[inbuf]), %%xmm12\n\t" + + "pxor %%xmm13, %%xmm3\n\t" /* xor IV with output */ + "movdqu 5*16(%[inbuf]), %%xmm13\n\t" + + "pxor %%xmm14, %%xmm4\n\t" /* xor IV with output */ + "movdqu 6*16(%[inbuf]), %%xmm14\n\t" + + "pxor %%xmm15, %%xmm8\n\t" /* xor IV with output */ + "movdqu 7*16(%[inbuf]), %%xmm5\n\t" + "pxor %%xmm12, %%xmm9\n\t" /* xor IV with output */ + "movdqu %%xmm1, 0*16(%[outbuf])\n\t" + "pxor %%xmm13, %%xmm10\n\t" /* xor IV with output */ + "movdqu %%xmm2, 1*16(%[outbuf])\n\t" + "pxor %%xmm14, %%xmm11\n\t" /* xor IV with output */ + "movdqu %%xmm3, 2*16(%[outbuf])\n\t" + "movdqu %%xmm4, 3*16(%[outbuf])\n\t" + "movdqu %%xmm8, 4*16(%[outbuf])\n\t" + "movdqu %%xmm9, 5*16(%[outbuf])\n\t" + "movdqu %%xmm10, 6*16(%[outbuf])\n\t" + "movdqu %%xmm11, 7*16(%[outbuf])\n\t" + + : /* No output */ + : [inbuf] "r" (inbuf), + [outbuf] "r" (outbuf) + : "memory"); + + outbuf += 8*BLOCKSIZE; + inbuf += 8*BLOCKSIZE; + } + + aesni_cleanup_7_15(); + } +#endif + + for ( ;nblocks >= 4 ; nblocks -= 4 ) { asm volatile ("movdqu 0*16(%[inbuf]), %%xmm1\n\t" /* load input blocks */ @@ -1386,7 +2216,142 @@ aesni_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg, outbuf += BLOCKSIZE; } - for ( ;nblocks > 3 ; nblocks -= 4 ) +#ifdef __x86_64__ + if (nblocks >= 8) + { + aesni_prepare_7_15_variable; + + aesni_prepare_7_15(); + + asm volatile ("movdqu %[l0], %%xmm7\n\t" + : + : [l0] "m" (*c->u_mode.ocb.L[0]) + : "memory" ); + + for ( ;nblocks >= 8 ; nblocks -= 8 ) + { + n += 4; + l = ocb_get_l(c, n); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + /* Checksum_i = Checksum_{i-1} xor P_i */ + /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ + + asm volatile ("movdqu %[l1], %%xmm10\n\t" + "movdqu %[inbuf0], %%xmm1\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm1, %%xmm6\n\t" + "pxor %%xmm5, %%xmm1\n\t" + "movdqa %%xmm5, %%xmm12\n\t" + : + : [l1] "m" (*c->u_mode.ocb.L[1]), + [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" + "pxor %%xmm10, %%xmm5\n\t" + "pxor %%xmm2, %%xmm6\n\t" + "pxor %%xmm5, %%xmm2\n\t" + "movdqa %%xmm5, %%xmm13\n\t" + : + : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm3, %%xmm6\n\t" + "pxor %%xmm5, %%xmm3\n\t" + "movdqa %%xmm5, %%xmm14\n\t" + : + : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[l3], %%xmm15\n\t" + "movdqu %[inbuf3], %%xmm4\n\t" + "pxor %%xmm15, %%xmm5\n\t" + "pxor %%xmm4, %%xmm6\n\t" + "pxor %%xmm5, %%xmm4\n\t" + "movdqa %%xmm5, %%xmm15\n\t" + : + : [l3] "m" (*l), + [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) + : "memory" ); + + n += 4; + l = ocb_get_l(c, n); + + asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm8, %%xmm6\n\t" + "pxor %%xmm5, %%xmm8\n\t" + "movdqu %%xmm5, %[outbuf4]\n\t" + : [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) + : [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" + "pxor %%xmm10, %%xmm5\n\t" + "pxor %%xmm9, %%xmm6\n\t" + "pxor %%xmm5, %%xmm9\n\t" + "movdqu %%xmm5, %[outbuf5]\n\t" + : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)) + : [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm10, %%xmm6\n\t" + "pxor %%xmm5, %%xmm10\n\t" + "movdqu %%xmm5, %[outbuf6]\n\t" + : [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)) + : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[l7], %%xmm11\n\t" + "pxor %%xmm11, %%xmm5\n\t" + "movdqu %[inbuf7], %%xmm11\n\t" + "pxor %%xmm11, %%xmm6\n\t" + "pxor %%xmm5, %%xmm11\n\t" + : + : [l7] "m" (*l), + [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)) + : "memory" ); + + do_aesni_enc_vec8 (ctx); + + asm volatile ("pxor %%xmm12, %%xmm1\n\t" + "pxor %%xmm13, %%xmm2\n\t" + "movdqu %[outbuf4],%%xmm0\n\t" + "movdqu %[outbuf5],%%xmm12\n\t" + "movdqu %[outbuf6],%%xmm13\n\t" + "pxor %%xmm14, %%xmm3\n\t" + "pxor %%xmm15, %%xmm4\n\t" + "pxor %%xmm0, %%xmm8\n\t" + "pxor %%xmm12, %%xmm9\n\t" + "pxor %%xmm13, %%xmm10\n\t" + "pxor %%xmm5, %%xmm11\n\t" + "movdqu %%xmm1, %[outbuf0]\n\t" + "movdqu %%xmm2, %[outbuf1]\n\t" + "movdqu %%xmm3, %[outbuf2]\n\t" + "movdqu %%xmm4, %[outbuf3]\n\t" + "movdqu %%xmm8, %[outbuf4]\n\t" + "movdqu %%xmm9, %[outbuf5]\n\t" + "movdqu %%xmm10, %[outbuf6]\n\t" + "movdqu %%xmm11, %[outbuf7]\n\t" + : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), + [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)), + [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), + [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), + [outbuf4] "+m" (*(outbuf + 4 * BLOCKSIZE)), + [outbuf5] "+m" (*(outbuf + 5 * BLOCKSIZE)), + [outbuf6] "+m" (*(outbuf + 6 * BLOCKSIZE)), + [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) + : + : "memory" ); + + outbuf += 8*BLOCKSIZE; + inbuf += 8*BLOCKSIZE; + } + + aesni_cleanup_7_15(); + } +#endif + + for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = ocb_get_l(c, n); @@ -1394,9 +2359,9 @@ aesni_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg, /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Checksum_i = Checksum_{i-1} xor P_i */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ - asm volatile ("movdqu %[l0], %%xmm0\n\t" + asm volatile ("movdqu %[l0], %%xmm4\n\t" "movdqu %[inbuf0], %%xmm1\n\t" - "pxor %%xmm0, %%xmm5\n\t" + "pxor %%xmm4, %%xmm5\n\t" "pxor %%xmm1, %%xmm6\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm5, %[outbuf0]\n\t" @@ -1414,19 +2379,17 @@ aesni_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg, : [l1] "m" (*c->u_mode.ocb.L[1]), [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l2], %%xmm0\n\t" - "movdqu %[inbuf2], %%xmm3\n\t" - "pxor %%xmm0, %%xmm5\n\t" + asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm4, %%xmm5\n\t" "pxor %%xmm3, %%xmm6\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm5, %[outbuf2]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)) - : [l2] "m" (*c->u_mode.ocb.L[0]), - [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l3], %%xmm0\n\t" + asm volatile ("movdqu %[l3], %%xmm4\n\t" + "pxor %%xmm4, %%xmm5\n\t" "movdqu %[inbuf3], %%xmm4\n\t" - "pxor %%xmm0, %%xmm5\n\t" "pxor %%xmm4, %%xmm6\n\t" "pxor %%xmm5, %%xmm4\n\t" : @@ -1551,7 +2514,142 @@ aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, outbuf += BLOCKSIZE; } - for ( ;nblocks > 3 ; nblocks -= 4 ) +#ifdef __x86_64__ + if (nblocks >= 8) + { + aesni_prepare_7_15_variable; + + aesni_prepare_7_15(); + + asm volatile ("movdqu %[l0], %%xmm7\n\t" + : + : [l0] "m" (*c->u_mode.ocb.L[0]) + : "memory" ); + + for ( ;nblocks >= 8 ; nblocks -= 8 ) + { + n += 4; + l = ocb_get_l(c, n); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ + /* Checksum_i = Checksum_{i-1} xor P_i */ + + asm volatile ("movdqu %[l1], %%xmm10\n\t" + "movdqu %[inbuf0], %%xmm1\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm1\n\t" + "movdqa %%xmm5, %%xmm12\n\t" + : + : [l1] "m" (*c->u_mode.ocb.L[1]), + [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" + "pxor %%xmm10, %%xmm5\n\t" + "pxor %%xmm5, %%xmm2\n\t" + "movdqa %%xmm5, %%xmm13\n\t" + : + : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm3\n\t" + "movdqa %%xmm5, %%xmm14\n\t" + : + : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[l3], %%xmm0\n\t" + "movdqu %[inbuf3], %%xmm4\n\t" + "pxor %%xmm0, %%xmm5\n\t" + "pxor %%xmm5, %%xmm4\n\t" + "movdqa %%xmm5, %%xmm15\n\t" + : + : [l3] "m" (*l), + [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) + : "memory" ); + + n += 4; + l = ocb_get_l(c, n); + + asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm8\n\t" + "movdqu %%xmm5, %[outbuf4]\n\t" + : [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) + : [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" + "pxor %%xmm10, %%xmm5\n\t" + "pxor %%xmm5, %%xmm9\n\t" + "movdqu %%xmm5, %[outbuf5]\n\t" + : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)) + : [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm10\n\t" + "movdqu %%xmm5, %[outbuf6]\n\t" + : [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)) + : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[l7], %%xmm0\n\t" + "movdqu %[inbuf7], %%xmm11\n\t" + "pxor %%xmm0, %%xmm5\n\t" + "pxor %%xmm5, %%xmm11\n\t" + : + : [l7] "m" (*l), + [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)) + : "memory" ); + + do_aesni_dec_vec8 (ctx); + + asm volatile ("pxor %%xmm12, %%xmm1\n\t" + "pxor %%xmm13, %%xmm2\n\t" + "movdqu %[outbuf4],%%xmm0\n\t" + "movdqu %[outbuf5],%%xmm12\n\t" + "movdqu %[outbuf6],%%xmm13\n\t" + "pxor %%xmm14, %%xmm3\n\t" + "pxor %%xmm15, %%xmm4\n\t" + "pxor %%xmm0, %%xmm8\n\t" + "pxor %%xmm12, %%xmm9\n\t" + "pxor %%xmm13, %%xmm10\n\t" + "pxor %%xmm5, %%xmm11\n\t" + "movdqu %%xmm1, %[outbuf0]\n\t" + "movdqu %%xmm2, %[outbuf1]\n\t" + "movdqu %%xmm3, %[outbuf2]\n\t" + "movdqu %%xmm4, %[outbuf3]\n\t" + "movdqu %%xmm8, %[outbuf4]\n\t" + "movdqu %%xmm9, %[outbuf5]\n\t" + "movdqu %%xmm10, %[outbuf6]\n\t" + "movdqu %%xmm11, %[outbuf7]\n\t" + "pxor %%xmm2, %%xmm1\n\t" + "pxor %%xmm4, %%xmm1\n\t" + "pxor %%xmm9, %%xmm1\n\t" + "pxor %%xmm11, %%xmm1\n\t" + "pxor %%xmm3, %%xmm6\n\t" + "pxor %%xmm8, %%xmm6\n\t" + "pxor %%xmm10, %%xmm6\n\t" + "pxor %%xmm1, %%xmm6\n\t" + : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), + [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)), + [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), + [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), + [outbuf4] "+m" (*(outbuf + 4 * BLOCKSIZE)), + [outbuf5] "+m" (*(outbuf + 5 * BLOCKSIZE)), + [outbuf6] "+m" (*(outbuf + 6 * BLOCKSIZE)), + [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) + : + : "memory" ); + + outbuf += 8*BLOCKSIZE; + inbuf += 8*BLOCKSIZE; + } + + aesni_cleanup_7_15(); + } +#endif + + for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = ocb_get_l(c, n); @@ -1559,9 +2657,9 @@ aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ /* Checksum_i = Checksum_{i-1} xor P_i */ - asm volatile ("movdqu %[l0], %%xmm0\n\t" + asm volatile ("movdqu %[l0], %%xmm4\n\t" "movdqu %[inbuf0], %%xmm1\n\t" - "pxor %%xmm0, %%xmm5\n\t" + "pxor %%xmm4, %%xmm5\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm5, %[outbuf0]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)) @@ -1577,14 +2675,12 @@ aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, : [l1] "m" (*c->u_mode.ocb.L[1]), [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l2], %%xmm0\n\t" - "movdqu %[inbuf2], %%xmm3\n\t" - "pxor %%xmm0, %%xmm5\n\t" + asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm4, %%xmm5\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm5, %[outbuf2]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)) - : [l2] "m" (*c->u_mode.ocb.L[0]), - [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[l3], %%xmm0\n\t" "movdqu %[inbuf3], %%xmm4\n\t" @@ -1722,16 +2818,115 @@ _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, abuf += BLOCKSIZE; } - for ( ;nblocks > 3 ; nblocks -= 4 ) +#ifdef __x86_64__ + if (nblocks >= 8) + { + aesni_prepare_7_15_variable; + + aesni_prepare_7_15(); + + asm volatile ("movdqu %[l0], %%xmm7\n\t" + "movdqu %[l1], %%xmm12\n\t" + : + : [l0] "m" (*c->u_mode.ocb.L[0]), + [l1] "m" (*c->u_mode.ocb.L[1]) + : "memory" ); + + for ( ;nblocks >= 8 ; nblocks -= 8 ) + { + n += 4; + l = ocb_get_l(c, n); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ + asm volatile ("movdqu %[abuf0], %%xmm1\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm1\n\t" + : + : [abuf0] "m" (*(abuf + 0 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[abuf1], %%xmm2\n\t" + "pxor %%xmm12, %%xmm5\n\t" + "pxor %%xmm5, %%xmm2\n\t" + : + : [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[abuf2], %%xmm3\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm3\n\t" + : + : [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[l3], %%xmm0\n\t" + "movdqu %[abuf3], %%xmm4\n\t" + "pxor %%xmm0, %%xmm5\n\t" + "pxor %%xmm5, %%xmm4\n\t" + : + : [l3] "m" (*l), + [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)) + : "memory" ); + + n += 4; + l = ocb_get_l(c, n); + + asm volatile ("movdqu %[abuf4], %%xmm8\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm8\n\t" + : + : [abuf4] "m" (*(abuf + 4 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[abuf5], %%xmm9\n\t" + "pxor %%xmm12, %%xmm5\n\t" + "pxor %%xmm5, %%xmm9\n\t" + : + : [abuf5] "m" (*(abuf + 5 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[abuf6], %%xmm10\n\t" + "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm5, %%xmm10\n\t" + : + : [abuf6] "m" (*(abuf + 6 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqu %[l7], %%xmm0\n\t" + "movdqu %[abuf7], %%xmm11\n\t" + "pxor %%xmm0, %%xmm5\n\t" + "pxor %%xmm5, %%xmm11\n\t" + : + : [l7] "m" (*l), + [abuf7] "m" (*(abuf + 7 * BLOCKSIZE)) + : "memory" ); + + do_aesni_enc_vec8 (ctx); + + asm volatile ("pxor %%xmm2, %%xmm1\n\t" + "pxor %%xmm3, %%xmm1\n\t" + "pxor %%xmm4, %%xmm1\n\t" + "pxor %%xmm8, %%xmm1\n\t" + "pxor %%xmm9, %%xmm6\n\t" + "pxor %%xmm10, %%xmm6\n\t" + "pxor %%xmm11, %%xmm6\n\t" + "pxor %%xmm1, %%xmm6\n\t" + : + : + : "memory" ); + + abuf += 8*BLOCKSIZE; + } + + aesni_cleanup_7_15(); + } +#endif + + for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = ocb_get_l(c, n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ - asm volatile ("movdqu %[l0], %%xmm0\n\t" + asm volatile ("movdqu %[l0], %%xmm4\n\t" "movdqu %[abuf0], %%xmm1\n\t" - "pxor %%xmm0, %%xmm5\n\t" + "pxor %%xmm4, %%xmm5\n\t" "pxor %%xmm5, %%xmm1\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), @@ -1745,9 +2940,8 @@ _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, : [l1] "m" (*c->u_mode.ocb.L[1]), [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l2], %%xmm0\n\t" - "movdqu %[abuf2], %%xmm3\n\t" - "pxor %%xmm0, %%xmm5\n\t" + asm volatile ("movdqu %[abuf2], %%xmm3\n\t" + "pxor %%xmm4, %%xmm5\n\t" "pxor %%xmm5, %%xmm3\n\t" : : [l2] "m" (*c->u_mode.ocb.L[0]), ----------------------------------------------------------------------- Summary of changes: cipher/cipher-internal.h | 2 +- cipher/cipher-xts.c | 3 +- cipher/cipher.c | 1 + cipher/rijndael-aesni.c | 1539 +++++++++++++++++++++++++++++++++++++++++++++- cipher/rijndael.c | 84 +++ src/cipher.h | 3 + 6 files changed, 1603 insertions(+), 29 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 10 12:38:17 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 10 Jan 2018 12:38:17 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-9-g39f1abc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 39f1abce90094bdbb03c38bb3aadf0db1d8147e6 (commit) from 08a7a0db7169ec6ab0abc2468fdcd16a8e06d4ce (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 39f1abce90094bdbb03c38bb3aadf0db1d8147e6 Author: Andre Heinecke Date: Wed Jan 10 12:32:16 2018 +0100 Change PGP/Inline behavior * src/mail.cpp (Mail::append_to_inline_body): New. (Mail::inline_body_to_body): Put cached body into oom body. * src/mail.h: Update accordingly. * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Call inline_body_to_body. * src/mimemaker.cpp (sink_string_write): New. (finalize_message): Don't change message class for inline. (create_top_encryption_header): No MIME header for inline. (mime_encrypt): Use sink_string_write if inline. -- Instead of our nice trick to do the S/MIME to MIME conversion with a text/plain part we now update the body. This is because Exchange Online did not like our trick. The new code should be a bit more robust. And yes caching stuff in the mail object is my hammer. GnuPG-Bug-Id: T3662 diff --git a/src/mail.cpp b/src/mail.cpp index 7f709eb..39342b1 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2413,3 +2413,21 @@ Mail::take_cached_recipients() m_cached_recipients = nullptr; return ret; } + +void +Mail::append_to_inline_body (const std::string &data) +{ + m_inline_body += data; +} + +int +Mail::inline_body_to_body() +{ + if (m_inline_body.empty()) + { + return 0; + } + int ret = put_oom_string (m_mailitem, "Body", m_inline_body.c_str ()); + m_inline_body = std::string(); + return ret; +} diff --git a/src/mail.h b/src/mail.h index 48141b3..42052e2 100644 --- a/src/mail.h +++ b/src/mail.h @@ -340,6 +340,13 @@ public: /** Check if the mail should be encrypted "inline" */ bool should_inline_crypt () const {return m_do_inline;} + + /** Append data to a cached inline body. Helper to do this + on MAPI level and later add it through OOM */ + void append_to_inline_body (const std::string &data); + + /** Set the inline body as OOM body property. */ + int inline_body_to_body (); private: void update_categories (); void update_body (); @@ -374,5 +381,6 @@ private: std::string m_orig_body; bool m_do_inline; bool m_is_gsuite; /* Are we on a gsuite account */ + std::string m_inline_body; }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index ae4aa66..88bac05 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -360,6 +360,14 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_debug ("%s:%s: Body found after encryption %p.", SRCNAME, __func__, m_object); + if (m_mail->should_inline_crypt ()) + { + if (m_mail->inline_body_to_body ()) + { + log_debug ("%s:%s: Inline body to body failed %p.", + SRCNAME, __func__, m_object); + } + } const auto body = m_mail->get_body(); if (body.size() > 10 && !strncmp (body.c_str(), "-----BEGIN", 10)) { diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index fe8d4b5..057df95 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -95,6 +95,14 @@ sink_std_write (sink_t sink, const void *data, size_t datalen) return 0; } +int +sink_string_write (sink_t sink, const void *data, size_t datalen) +{ + Mail *mail = static_cast(sink->cb_data); + mail->append_to_inline_body (std::string((char*)data, datalen)); + return 0; +} + /* Write method used with a sink_t that contains a file object. */ int sink_file_write (sink_t sink, const void *data, size_t datalen) @@ -1139,7 +1147,7 @@ static int finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table, protocol_t protocol, int encrypt, bool is_inline = false) { - HRESULT hr; + HRESULT hr = 0; SPropValue prop; SPropTagArray proparray; @@ -1154,7 +1162,13 @@ finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table, prop.Value.lpszA = strdup ("IPM.Note.InfoPathForm.GpgOLS.SMIME.MultipartSigned"); } - hr = message->SetProps(1, &prop, NULL); + if (!is_inline) + { + /* For inline we stick with IPM.Note because Exchange Online would + error out if we tried our S/MIME conversion trick with a text + plain message */ + hr = message->SetProps(1, &prop, NULL); + } xfree(prop.Value.lpszA); if (hr) { @@ -1875,6 +1889,10 @@ create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary, if (is_inline) { *boundary = 0; + rc = 0; + /* This would be nice and worked for Google Sync but it failed + for Microsoft Exchange Online *sigh* so we put the body + instead into the oom body property and stick with IPM Note. rc = write_multistring (sink, "MIME-Version: 1.0\r\n" "Content-Type: text/plain;\r\n" @@ -1882,6 +1900,7 @@ create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary, "Content-Transfer-Encoding: 7BIT\r\n" "\r\n", NULL); + */ } else if (protocol == PROTOCOL_SMIME) { @@ -1939,7 +1958,7 @@ mime_encrypt (LPMESSAGE message, HWND hwnd, { int result = -1; int rc; - LPATTACH attach; + LPATTACH attach = nullptr; struct sink_s sinkmem; sink_t sink = &sinkmem; struct sink_s encsinkmem; @@ -1955,10 +1974,6 @@ mime_encrypt (LPMESSAGE message, HWND hwnd, memset (sink, 0, sizeof *sink); memset (encsink, 0, sizeof *encsink); - attach = create_mapi_attachment (message, sink); - if (!attach) - return -1; - /* Get the attachment info and the body. We need to do this before creating the engine's filter because sending the cancel to the engine with nothing for the engine to process. Will result @@ -1999,6 +2014,18 @@ mime_encrypt (LPMESSAGE message, HWND hwnd, is_inline = false; } + if (!is_inline || !mail) + { + attach = create_mapi_attachment (message, sink); + if (!attach) + return -1; + } + else + { + sink->cb_data = mail; + sink->writefnc = sink_string_write; + } + /* Prepare the encryption. We do this early as it is quite common that some recipient keys are not available and thus the encryption will fail early. */ @@ -2081,7 +2108,7 @@ mime_encrypt (LPMESSAGE message, HWND hwnd, if (*boundary && (rc = write_boundary (sink, boundary, 1))) goto failure; - if (close_mapi_attachment (&attach, sink)) + if (attach && close_mapi_attachment (&attach, sink)) goto failure; if (finalize_message (message, att_table, protocol, 1, is_inline)) @@ -2091,7 +2118,10 @@ mime_encrypt (LPMESSAGE message, HWND hwnd, failure: engine_cancel (filter); - cancel_mapi_attachment (&attach, sink); + if (attach) + { + cancel_mapi_attachment (&attach, sink); + } xfree (body); mapi_release_attach_table (att_table); xfree (my_sender); ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 18 ++++++++++++++++++ src/mail.h | 8 ++++++++ src/mailitem-events.cpp | 8 ++++++++ src/mimemaker.cpp | 48 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 73 insertions(+), 9 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 10 14:26:58 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 10 Jan 2018 14:26:58 +0100 Subject: [git] gnupg-doc - branch, master, updated. 7794c9fb38882b5e6d60226695887c804b9aaf62 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 7794c9fb38882b5e6d60226695887c804b9aaf62 (commit) from ed7296a3bd46a46352630d772a8b9753083441b2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7794c9fb38882b5e6d60226695887c804b9aaf62 Author: Ben McGinnes Date: Thu Jan 11 00:25:25 2018 +1100 GPG with PHP * Added link to guide to using PHP and GPG together following discussion with the author. diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index 5be52f8..7d100f2 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -103,3 +103,18 @@ This HOWTO is available: - as plain text ( [[http://codesorcery.net/old/mutt/][en]] ) + +** PHP-GnuPG HOWTO + + With the preponderance of javascript based OpenPGP solutions to + various functions on the web, the desire to perform certain types + of server side functions on a PHP driven website also has its + merits. + + While PHP support for GPGME is either lacking, or too arcane for + most developers to decipher, or both; Piotr Mase?kowski at + [[https://maslosoft.com/][Maslosoft]] has an alternative guide using the CLI programs. + + This HOWTO is available as: + + - as an online HTML article ( [[https://maslosoft.com/blog/2017/09/12/using-gpg-with-php-on-server/][en]] ) ----------------------------------------------------------------------- Summary of changes: web/documentation/howtos.org | 15 +++++++++++++++ 1 file changed, 15 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 10 17:39:49 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 10 Jan 2018 17:39:49 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.3-116-g81d7181 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 81d71818d054a5faa9153fd52a4b79bbbb71e9d5 (commit) via 4e2ba546cdccbbc6d3e29867ee5671fd44d74e67 (commit) via 8217cd49364b9f81b390f7ca6a608dd946f93efc (commit) from 945381c4c26ffa5a9b1b0781294d0440e55d2ade (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 81d71818d054a5faa9153fd52a4b79bbbb71e9d5 Author: Werner Koch Date: Wed Jan 10 17:33:50 2018 +0100 gpg: Add stub function for encrypting AEAD. * g10/cipher.c (cipher_filter): Rename to cipher_filter_cfb. * g10/cipher-aead.c: New. Right now only with a stub function. * g10/Makefile.am (gpg_sources): Add file. * g10/encrypt.c (encrypt_simple): Push either cipher_filter_cfb or cipher_filter_aead. (encrypt_crypt): Ditto. (encrypt_filter): Ditto. * g10/sign.c (sign_symencrypt_file): Ditto. Signed-off-by: Werner Koch diff --git a/g10/Makefile.am b/g10/Makefile.am index cc4ef5c..cba65b2 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -132,6 +132,7 @@ gpg_sources = server.c \ decrypt.c \ decrypt-data.c \ cipher.c \ + cipher-aead.c \ encrypt.c \ sign.c \ verify.c \ diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c new file mode 100644 index 0000000..bf0afcf --- /dev/null +++ b/g10/cipher-aead.c @@ -0,0 +1,67 @@ +/* cipher-aead.c - Enciphering filter for AEAD modes + * Copyright (C) 2018 Werner koch + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0+ + */ + +#include +#include +#include +#include +#include + +#include "gpg.h" +#include "../common/status.h" +#include "../common/iobuf.h" +#include "../common/util.h" +#include "filter.h" +#include "packet.h" +#include "options.h" +#include "main.h" + + +/* + * This filter is used to encipher data with an AEAD algorithm + */ +int +cipher_filter_aead (void *opaque, int control, + iobuf_t a, byte *buf, size_t *ret_len) +{ + cipher_filter_context_t *cfx = opaque; + size_t size = *ret_len; + int rc = 0; + + if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */ + { + rc = -1; /* not yet used */ + } + else if (control == IOBUFCTRL_FLUSH) /* encrypt */ + { + log_assert (a); + rc = GPG_ERR_NOT_IMPLEMENTED; + } + else if (control == IOBUFCTRL_FREE) + { + gcry_cipher_close (cfx->cipher_hd); + } + else if (control == IOBUFCTRL_DESC) + { + mem2str (buf, "cipher_filter_aead", *ret_len); + } + + return rc; +} diff --git a/g10/cipher.c b/g10/cipher.c index b950d0c..ad7399d 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -1,4 +1,4 @@ -/* cipher.c - En-/De-ciphering filter +/* cipher.c - Enciphering filter for the old CFB mode. * Copyright (C) 1998-2003, 2006, 2009 Free Software Foundation, Inc. * Copyright (C) 1998-2003, 2006, 2009, 2017 Werner koch * @@ -117,7 +117,8 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) * This filter is used to en/de-cipher data with a symmetric algorithm */ int -cipher_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len) +cipher_filter_cfb (void *opaque, int control, + iobuf_t a, byte *buf, size_t *ret_len) { cipher_filter_context_t *cfx = opaque; size_t size = *ret_len; @@ -177,7 +178,7 @@ cipher_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len) } else if (control == IOBUFCTRL_DESC) { - mem2str (buf, "cipher_filter", *ret_len); + mem2str (buf, "cipher_filter_cfb", *ret_len); } return rc; diff --git a/g10/encrypt.c b/g10/encrypt.c index 2951a45..01feb4a 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -409,7 +409,10 @@ encrypt_simple (const char *filename, int mode, int use_seskey) /* Register the cipher filter. */ if (mode) - iobuf_push_filter ( out, cipher_filter, &cfx ); + iobuf_push_filter (out, + cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &cfx ); /* Register the compress filter. */ if ( do_compress ) @@ -800,7 +803,10 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, cfx.datalen = filesize && !do_compress ? filesize : 0; /* Register the cipher filter. */ - iobuf_push_filter (out, cipher_filter, &cfx); + iobuf_push_filter (out, + cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &cfx); /* Register the compress filter. */ if (do_compress) @@ -959,7 +965,10 @@ encrypt_filter (void *opaque, int control, return rc; } - iobuf_push_filter (a, cipher_filter, &efx->cfx); + iobuf_push_filter (a, + efx->cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &efx->cfx); efx->header_okay = 1; } diff --git a/g10/filter.h b/g10/filter.h index 9e4b1e5..2924355 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -145,8 +145,12 @@ void push_compress_filter2(iobuf_t out,compress_filter_context_t *zfx, int algo,int rel); /*-- cipher.c --*/ -int cipher_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); +int cipher_filter_cfb (void *opaque, int control, + iobuf_t chain, byte *buf, size_t *ret_len); + +/*-- cipher-aead.c --*/ +int cipher_filter_aead (void *opaque, int control, + iobuf_t chain, byte *buf, size_t *ret_len); /*-- textfilter.c --*/ int text_filter( void *opaque, int control, diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index 8c156d2..f879838 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -2573,7 +2573,7 @@ encrypted (const char *option, int argc, char *argv[], void *cookie) cfx->datalen = 0; - filter_push (out, cipher_filter, cfx, PKT_ENCRYPTED, cfx->datalen == 0); + filter_push (out, cipher_filter_cfb, cfx, PKT_ENCRYPTED, cfx->datalen == 0); debug ("Wrote encrypted packet:\n"); diff --git a/g10/sign.c b/g10/sign.c index f8a1241..051ab59 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1379,7 +1379,10 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) } /* Push the encryption filter */ - iobuf_push_filter( out, cipher_filter, &cfx ); + iobuf_push_filter (out, + cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &cfx); /* Push the compress filter */ if (default_compress_algo()) commit 4e2ba546cdccbbc6d3e29867ee5671fd44d74e67 Author: Werner Koch Date: Wed Jan 10 17:07:11 2018 +0100 gpg: New option --force-aead * g10/dek.h (DEK): Turn fields use_mdc, algo_printed and symmetric into single bit vars. Make sure they are always set to 1 or 0. (DEK): New field use_aead. * g10/options.h (struct opt): New field force_aead. * g10/pkclist.c (select_aead_from_pklist): New. * g10/gpg.c (oForceAEAD): New const. (opts): New options "--force-aead". (main): Set new option. * g10/encrypt.c (use_aead): New. (encrypt_simple): Implement new flags DEK.use_aead. (encrypt_crypt): Ditto. (encrypt_filter): Ditto. * g10/sign.c (sign_symencrypt_file): Ditto. -- This patch should be enough to detect whether AEAD can be used. Not tested. Signed-off-by: Werner Koch diff --git a/g10/dek.h b/g10/dek.h index 666810c..64e98fc 100644 --- a/g10/dek.h +++ b/g10/dek.h @@ -1,5 +1,5 @@ /* dek.h - The data encryption key structure. - * Copyright (C) 2014 Werner Koch + * Copyright (C) 2014, 2017 Werner Koch * * This file is part of GnuPG. * @@ -26,14 +26,25 @@ typedef struct int algo; /* The length of the key (in bytes). */ int keylen; + /* Whether we've already printed information about this key. This - is currently only used in decrypt_data() and only if we are in - verbose mode. */ - int algo_info_printed; - int use_mdc; + * is currently only used in decrypt_data() and only if we are in + * verbose mode. */ + int algo_info_printed : 1; + + /* AEAD shall be used. */ + int use_aead : 1; + + /* MDC shall be used. */ + int use_mdc : 1; + /* This key was read from a SK-ESK packet (see proc_symkey_enc). */ - int symmetric; - byte key[32]; /* This is the largest used keylen (256 bit). */ + int symmetric : 1; + + /* This is the largest used keylen (256 bit). */ + byte key[32]; + + /* The cacheid for the S2K. */ char s2k_cacheid[1+16+1]; } DEK; diff --git a/g10/encrypt.c b/g10/encrypt.c index 263226a..2951a45 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -109,6 +109,47 @@ encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey) } +/* Return true if we shall use AEAD mode. */ +int +use_aead (pk_list_t pk_list, int algo) +{ + int can_use; + + if (!opt.flags.rfc4880bis) + { + if (opt.force_aead) + log_info ("Warning: Option %s currently requires option '%s'\n", + "--force-aead", "--rfc4880bis"); + return 0; + } + + can_use = openpgp_cipher_get_algo_blklen (algo) != 16; + + /* With --force-mdc we clearly do not want AEAD. */ + if (opt.force_mdc) + return 0; + + /* However with --force-aead we want AEAD. */ + if (opt.force_aead) + { + if (!can_use) + log_info ("Warning: request to use AEAD ignored for cipher '%s'\n", + openpgp_cipher_algo_name (algo)); + return 1; + } + + /* AEAD does noly work with 128 bit cipher blocklength. */ + if (!can_use) + return 0; + + /* If all keys support AEAD we can use it. */ + if (select_aead_from_pklist (pk_list)) + return 1; + + return 0; /* No AEAD. */ +} + + /* We try very hard to use a MDC */ int use_mdc (pk_list_t pk_list,int algo) @@ -265,10 +306,15 @@ encrypt_simple (const char *filename, int mode, int use_seskey) log_info(_("using cipher %s\n"), openpgp_cipher_algo_name (cfx.dek->algo)); - cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo); + if (use_aead (NULL, cfx.dek->algo)) + cfx.dek->use_aead = 1; + else + cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); } - if (do_compress && cfx.dek && cfx.dek->use_mdc + if (do_compress + && cfx.dek + && (cfx.dek->use_mdc || cfx.dek->use_aead) && is_file_compressed(filename, &rc)) { if (opt.verbose) @@ -368,7 +414,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) /* Register the compress filter. */ if ( do_compress ) { - if (cfx.dek && cfx.dek->use_mdc) + if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead)) zfx.new_ctb = 1; push_compress_filter (out, &zfx, default_compress_algo()); } @@ -676,14 +722,18 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, gnupg_status_compliance_flag (CO_DE_VS), NULL); - cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo); + if (use_aead (pk_list, cfx.dek->algo)) + cfx.dek->use_aead = 1; + else + cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo); /* Only do the is-file-already-compressed check if we are using a - MDC. This forces compressed files to be re-compressed if we do - not have a MDC to give some protection against chosen ciphertext - attacks. */ - - if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2)) + * MDC or AEAD. This forces compressed files to be re-compressed if + * we do not have a MDC to give some protection against chosen + * ciphertext attacks. */ + if (do_compress + && (cfx.dek->use_mdc || cfx.dek->use_aead) + && is_file_compressed (filename, &rc2)) { if (opt.verbose) log_info(_("'%s' already compressed\n"), filename); @@ -777,7 +827,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, /* Algo 0 means no compression. */ if (compr_algo) { - if (cfx.dek && cfx.dek->use_mdc) + if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead)) zfx.new_ctb = 1; push_compress_filter (out,&zfx,compr_algo); } @@ -887,7 +937,10 @@ encrypt_filter (void *opaque, int control, efx->cfx.dek->algo = opt.def_cipher_algo; } - efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo); + if (use_aead (efx->pk_list, efx->cfx.dek->algo)) + efx->cfx.dek->use_aead = 1; + else + efx->cfx.dek->use_mdc = !!use_mdc (efx->pk_list,efx->cfx.dek->algo); make_session_key ( efx->cfx.dek ); if (DBG_CRYPTO) diff --git a/g10/gpg.c b/g10/gpg.c index fadd2f0..a643388 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -304,6 +304,7 @@ enum cmd_and_opt_values oNoForceMDC, oDisableMDC, oNoDisableMDC, + oForceAEAD, oS2KMode, oS2KDigest, oS2KCipher, @@ -605,6 +606,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oDisableMDC, "disable-mdc", "@"), ARGPARSE_s_n (oNoDisableMDC, "no-disable-mdc", "@"), + ARGPARSE_s_n (oForceAEAD, "force-aead", "@"), + ARGPARSE_s_n (oDisableSignerUID, "disable-signer-uid", "@"), ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), @@ -2977,6 +2980,8 @@ main (int argc, char **argv) case oDisableMDC: opt.disable_mdc = 1; break; case oNoDisableMDC: opt.disable_mdc = 0; break; + case oForceAEAD: opt.force_aead = 1; break; + case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break; case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; diff --git a/g10/keydb.h b/g10/keydb.h index 7393768..9f6064b 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -232,6 +232,7 @@ int algo_available( preftype_t preftype, int algo, int select_algo_from_prefs( PK_LIST pk_list, int preftype, int request, const union pref_hint *hint); int select_mdc_from_pklist (PK_LIST pk_list); +int select_aead_from_pklist (pk_list_t pk_list); void warn_missing_mdc_from_pklist (PK_LIST pk_list); void warn_missing_aes_from_pklist (PK_LIST pk_list); diff --git a/g10/main.h b/g10/main.h index 6abc598..393a1b0 100644 --- a/g10/main.h +++ b/g10/main.h @@ -233,6 +233,7 @@ void display_online_help( const char *keyword ); /*-- encode.c --*/ int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); void encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey); +int use_aead (pk_list_t pk_list, int algo); int use_mdc (pk_list_t pk_list,int algo); int encrypt_symmetric (const char *filename ); int encrypt_store (const char *filename ); diff --git a/g10/options.h b/g10/options.h index 6ad1037..36bea69 100644 --- a/g10/options.h +++ b/g10/options.h @@ -95,6 +95,7 @@ struct int def_aead_algo; int force_mdc; int disable_mdc; + int force_aead; int def_digest_algo; int cert_digest_algo; int compress_algo; diff --git a/g10/pkclist.c b/g10/pkclist.c index a759672..b85efa4 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -1651,6 +1651,31 @@ select_mdc_from_pklist (PK_LIST pk_list) } +/* Select the AEAD flag from the pk_list. We can only use AEAD if all + * recipients support this feature. Returns true if AEAD can be used. */ +int +select_aead_from_pklist (PK_LIST pk_list) +{ + pk_list_t pkr; + int aead; + + if (!pk_list) + return 0; + + for (pkr = pk_list; pkr; pkr = pkr->next) + { + if (pkr->pk->user_id) /* selected by user ID */ + aead = pkr->pk->user_id->flags.aead; + else + aead = pkr->pk->flags.aead; + if (!aead) + return 0; /* At least one recipient does not support it. */ + } + + return 1; /* Can be used. */ +} + + /* Print a warning for all keys in PK_LIST missing the MDC feature. */ void warn_missing_mdc_from_pklist (PK_LIST pk_list) diff --git a/g10/sign.c b/g10/sign.c index 4cf0cd3..f8a1241 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1337,7 +1337,10 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) goto leave; } - cfx.dek->use_mdc = use_mdc (NULL, cfx.dek->algo); + if (use_aead (NULL, cfx.dek->algo)) + cfx.dek->use_aead = 1; + else + cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); /* now create the outfile */ rc = open_outfile (-1, fname, opt.armor? 1:0, 0, &out); @@ -1381,7 +1384,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) /* Push the compress filter */ if (default_compress_algo()) { - if (cfx.dek && cfx.dek->use_mdc) + if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead)) zfx.new_ctb = 1; push_compress_filter (out, &zfx,default_compress_algo() ); } commit 8217cd49364b9f81b390f7ca6a608dd946f93efc Author: Werner Koch Date: Wed Jan 10 11:42:38 2018 +0100 gpg: Add option and preference framework for AEAD. * common/openpgpdefs.h (aead_algo_t): New. (SIGSUBPKT_PREF_AEAD): New. * g10/gpg.c (oAEADAlgo, oPersonalAEADPreferences): New. (opts): New options --aead-algo and --personal-aead-preferences. (set_compliance_option): Clar aead algo. (main): Parse and check the new options * g10/options.h (struct opt): Add fields def_aead_algo and personal_aead_prefs. * g10/packet.h (PREFTYPE_AEAD): New enum value. (PKT_user_id): Add field flags.aead. (PKT_public_key): Add field flags.aead. * g10/pkclist.c (select_algo_from_prefs): Support PREFTYPE_AEAD. * g10/getkey.c (fixup_uidnode): Set AEAD flag. (merge_selfsigs): Ditto. * g10/kbnode.c (dump_kbnode): Show aead flag. * g10/keyedit.c (show_prefs): Ditto. (show_key_with_all_names_colon): Ditto. * g10/keygen.c (aead_presf, n_aead_prefs): New vars. (set_one_pref): Suppport PREFTYPE_AEAD. (keygen_set_std_prefs): Parse AEAD preferences. (keygen_get_std_prefs): Ditto. (add_feature_aead): New. (keygen_upd_std_prefs): Call that and build AEAD pref packet. * g10/main.h (DEFAULT_AEAD_ALGO): New const. * g10/misc.c (openpgp_aead_test_algo): New. (openpgp_aead_algo_name): New. (string_to_aead_algo): New. (default_aead_algo): New. -- This is only used in --rfc4880bis mode and not really tested. Signed-off-by: Werner Koch diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 85a4251..aeb3389 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -115,7 +115,8 @@ typedef enum SIGSUBPKT_FEATURES = 30, /* Feature flags. */ SIGSUBPKT_SIGNATURE = 32, /* Embedded signature. */ - SIGSUBPKT_ISSUER_FPR = 33, /* EXPERIMENTAL: Issuer fingerprint. */ + SIGSUBPKT_ISSUER_FPR = 33, /* Issuer fingerprint. */ + SIGSUBPKT_PREF_AEAD = 34, /* Preferred AEAD algorithms. */ SIGSUBPKT_FLAG_CRITICAL = 128 } @@ -144,6 +145,15 @@ cipher_algo_t; typedef enum { + AEAD_ALGO_NONE = 0, + AEAD_ALGO_EAX = 1, + AEAD_ALGO_OCB = 2 + } +aead_algo_t; + + +typedef enum + { PUBKEY_ALGO_RSA = 1, PUBKEY_ALGO_RSA_E = 2, /* RSA encrypt only (legacy). */ PUBKEY_ALGO_RSA_S = 3, /* RSA sign only (legacy). */ diff --git a/g10/getkey.c b/g10/getkey.c index dabd052..497dace 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2539,6 +2539,12 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated) if (p && n && (p[0] & 0x01)) uid->flags.mdc = 1; + /* See whether we have the AEAD feature. */ + uid->flags.aead = 0; + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n); + if (p && n && (p[0] & 0x01)) + uid->flags.aead = 1; + /* And the keyserver modify flag. */ uid->flags.ks_modify = 1; p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n); @@ -3357,6 +3363,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock) PKT_public_key *main_pk; prefitem_t *prefs; unsigned int mdc_feature; + unsigned int aead_feature; if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY) { @@ -3418,7 +3425,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock) * all preferences. * Do a similar thing for the MDC feature flag. */ prefs = NULL; - mdc_feature = 0; + mdc_feature = aead_feature = 0; for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) { if (k->pkt->pkttype == PKT_USER_ID @@ -3427,6 +3434,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock) { prefs = k->pkt->pkt.user_id->prefs; mdc_feature = k->pkt->pkt.user_id->flags.mdc; + aead_feature = k->pkt->pkt.user_id->flags.aead; break; } } @@ -3440,6 +3448,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock) xfree (pk->prefs); pk->prefs = copy_prefs (prefs); pk->flags.mdc = mdc_feature; + pk->flags.aead = aead_feature; } } } diff --git a/g10/gpg.c b/g10/gpg.c index 61e39b8..fadd2f0 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -245,6 +245,7 @@ enum cmd_and_opt_values oRFC2440Text, oNoRFC2440Text, oCipherAlgo, + oAEADAlgo, oDigestAlgo, oCertDigestAlgo, oCompressAlgo, @@ -371,6 +372,7 @@ enum cmd_and_opt_values oDefaultPreferenceList, oDefaultKeyserverURL, oPersonalCipherPreferences, + oPersonalAEADPreferences, oPersonalDigestPreferences, oPersonalCompressPreferences, oAgentProgram, @@ -668,6 +670,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"), ARGPARSE_s_i (oS2KCount, "s2k-count", "@"), ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"), + ARGPARSE_s_s (oAEADAlgo, "aead-algo", "@"), ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"), ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"), ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"), @@ -824,6 +827,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oDefaultPreferenceList, "default-preference-list", "@"), ARGPARSE_s_s (oDefaultKeyserverURL, "default-keyserver-url", "@"), ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-preferences","@"), + ARGPARSE_s_s (oPersonalAEADPreferences, "personal-aead-preferences","@"), ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-preferences","@"), ARGPARSE_s_s (oPersonalCompressPreferences, "personal-compress-preferences", "@"), @@ -835,6 +839,7 @@ static ARGPARSE_OPTS opts[] = { /* Aliases. I constantly mistype these, and assume other people do as well. */ ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-prefs", "@"), + ARGPARSE_s_s (oPersonalAEADPreferences, "personal-aead-prefs", "@"), ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-prefs", "@"), ARGPARSE_s_s (oPersonalCompressPreferences, "personal-compress-prefs", "@"), @@ -2125,6 +2130,7 @@ set_compliance_option (enum cmd_and_opt_values option) opt.escape_from = 1; opt.not_dash_escaped = 0; opt.def_cipher_algo = 0; + opt.def_aead_algo = 0; opt.def_digest_algo = 0; opt.cert_digest_algo = 0; opt.compress_algo = -1; @@ -2141,6 +2147,7 @@ set_compliance_option (enum cmd_and_opt_values option) opt.escape_from = 0; opt.not_dash_escaped = 0; opt.def_cipher_algo = 0; + opt.def_aead_algo = 0; opt.def_digest_algo = 0; opt.cert_digest_algo = 0; opt.compress_algo = -1; @@ -2157,6 +2164,7 @@ set_compliance_option (enum cmd_and_opt_values option) set_compliance_option (oOpenPGP); opt.compliance = CO_DE_VS; opt.force_mdc = 1; + opt.def_aead_algo = 0; /* Fixme: Change other options. */ break; @@ -2286,12 +2294,14 @@ main (int argc, char **argv) const char *trustdb_name = NULL; #endif /*!NO_TRUST_MODELS*/ char *def_cipher_string = NULL; + char *def_aead_string = NULL; char *def_digest_string = NULL; char *compress_algo_string = NULL; char *cert_digest_string = NULL; char *s2k_cipher_string = NULL; char *s2k_digest_string = NULL; char *pers_cipher_list = NULL; + char *pers_aead_list = NULL; char *pers_digest_list = NULL; char *pers_compress_list = NULL; int eyes_only=0; @@ -2355,6 +2365,7 @@ main (int argc, char **argv) opt.bz2_compress_level = -1; /* defaults to standard compress level */ /* note: if you change these lines, look at oOpenPGP */ opt.def_cipher_algo = 0; + opt.def_aead_algo = 0; opt.def_digest_algo = 0; opt.cert_digest_algo = 0; opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */ @@ -3113,6 +3124,9 @@ main (int argc, char **argv) case oCipherAlgo: def_cipher_string = xstrdup(pargs.r.ret_str); break; + case oAEADAlgo: + def_aead_string = xstrdup (pargs.r.ret_str); + break; case oDigestAlgo: def_digest_string = xstrdup(pargs.r.ret_str); break; @@ -3392,6 +3406,9 @@ main (int argc, char **argv) case oPersonalCipherPreferences: pers_cipher_list=pargs.r.ret_str; break; + case oPersonalAEADPreferences: + pers_aead_list = pargs.r.ret_str; + break; case oPersonalDigestPreferences: pers_digest_list=pargs.r.ret_str; break; @@ -3737,6 +3754,13 @@ main (int argc, char **argv) if ( openpgp_cipher_test_algo (opt.def_cipher_algo) ) log_error(_("selected cipher algorithm is invalid\n")); } + if (def_aead_string) + { + opt.def_aead_algo = string_to_aead_algo (def_aead_string); + xfree (def_aead_string); def_aead_string = NULL; + if (openpgp_aead_test_algo (opt.def_aead_algo)) + log_error(_("selected AEAD algorithm is invalid\n")); + } if( def_digest_string ) { opt.def_digest_algo = string_to_digest_algo (def_digest_string); xfree(def_digest_string); def_digest_string = NULL; @@ -3796,6 +3820,9 @@ main (int argc, char **argv) keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM)) log_error(_("invalid personal cipher preferences\n")); + if (pers_aead_list && keygen_set_std_prefs (pers_aead_list, PREFTYPE_AEAD)) + log_error(_("invalid personal AEAD preferences\n")); + if(pers_digest_list && keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH)) log_error(_("invalid personal digest preferences\n")); @@ -3861,6 +3888,12 @@ main (int argc, char **argv) badalg = openpgp_cipher_algo_name (opt.def_cipher_algo); badtype = PREFTYPE_SYM; } + else if(opt.def_aead_algo + && !algo_available(PREFTYPE_AEAD, opt.def_aead_algo, NULL)) + { + badalg = openpgp_aead_algo_name (opt.def_aead_algo); + badtype = PREFTYPE_AEAD; + } else if(opt.def_digest_algo && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL)) { @@ -3890,6 +3923,12 @@ main (int argc, char **argv) badalg, gnupg_compliance_option_string (opt.compliance)); break; + case PREFTYPE_AEAD: + log_info (_("AEAD algorithm '%s'" + " may not be used in %s mode\n"), + badalg, + gnupg_compliance_option_string (opt.compliance)); + break; case PREFTYPE_HASH: log_info (_("digest algorithm '%s'" " may not be used in %s mode\n"), @@ -3915,6 +3954,7 @@ main (int argc, char **argv) * is not. This is us being nice to the user informing her early * that the chosen algorithms are not available. We also check * and enforce this right before the actual operation. */ + /* FIXME: We also need to check the AEAD algo. */ if (opt.def_cipher_algo && ! gnupg_cipher_is_allowed (opt.compliance, cmd == aEncr diff --git a/g10/kbnode.c b/g10/kbnode.c index c2aaacd..64def05 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -415,13 +415,14 @@ dump_kbnode (KBNODE node) { PKT_public_key *pk = node->pkt->pkt.public_key; - log_printf (" keyid=%08lX a=%d u=%d %c%c%c%c\n", + log_printf (" keyid=%08lX a=%d u=%d %c%c%c%c%c\n", (ulong)keyid_from_pk( pk, NULL ), pk->pubkey_algo, pk->pubkey_usage, pk->has_expired? 'e':'.', pk->flags.revoked? 'r':'.', pk->flags.valid? 'v':'.', - pk->flags.mdc? 'm':'.'); + pk->flags.mdc? 'm':'.', + pk->flags.aead? 'a':'.'); } else log_printf ("\n"); diff --git a/g10/keyedit.c b/g10/keyedit.c index 8d86253..81344eb 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3118,7 +3118,7 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose) } tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_NONE)); } - if (uid->flags.mdc || !uid->flags.ks_modify) + if (uid->flags.mdc || uid->flags.aead || !uid->flags.ks_modify) { tty_printf ("\n "); tty_printf (_("Features: ")); @@ -3128,6 +3128,12 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose) tty_printf ("MDC"); any = 1; } + if (!uid->flags.aead) + { + if (any) + tty_printf (", "); + tty_printf ("AEAD"); + } if (!uid->flags.ks_modify) { if (any) @@ -3172,6 +3178,8 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose) } if (uid->flags.mdc) tty_printf (" [mdc]"); + if (uid->flags.aead) + tty_printf (" [aead]"); if (!uid->flags.ks_modify) tty_printf (" [no-ks-modify]"); tty_printf ("\n"); @@ -3317,6 +3325,8 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock) } if (uid->flags.mdc) es_fputs (",mdc", fp); + if (uid->flags.aead) + es_fputs (",aead", fp); if (!uid->flags.ks_modify) es_fputs (",no-ks-modify", fp); } diff --git a/g10/keygen.c b/g10/keygen.c index 912fa39..d5f7782 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -127,6 +127,9 @@ struct opaque_data_usage_and_pk { }; +/* FIXME: These globals vars are ugly. And using MAX_PREFS even for + * aeads is useless, given that we don't expects more than a very few + * algorithms. */ static int prefs_initialized = 0; static byte sym_prefs[MAX_PREFS]; static int nsym_prefs; @@ -134,7 +137,11 @@ static byte hash_prefs[MAX_PREFS]; static int nhash_prefs; static byte zip_prefs[MAX_PREFS]; static int nzip_prefs; -static int mdc_available,ks_modify; +static byte aead_prefs[MAX_PREFS]; +static int naead_prefs; +static int mdc_available; +static int ks_modify; +static int aead_available; static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey, const char *algostr, const char *usagestr, @@ -326,6 +333,8 @@ set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf) log_info(_("too many digest preferences\n")); else if(type==3) log_info(_("too many compression preferences\n")); + else if(type==4) + log_info(_("too many AEAD preferences\n")); else BUG(); @@ -346,10 +355,10 @@ set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf) int keygen_set_std_prefs (const char *string,int personal) { - byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS]; - int nsym=0, nhash=0, nzip=0, val, rc=0; + byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS], aead[MAX_PREFS]; + int nsym=0, nhash=0, nzip=0, naead=0, val, rc=0; int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */ - char dummy_string[20*4+1]; /* Enough for 20 items. */ + char dummy_string[25*4+1]; /* Enough for 25 items. */ if (!string || !ascii_strcasecmp (string, "default")) { @@ -383,6 +392,11 @@ keygen_set_std_prefs (const char *string,int personal) strcat(dummy_string,"S7 "); strcat(dummy_string,"S2 "); /* 3DES */ + if (opt.flags.rfc4880bis && !openpgp_aead_test_algo (AEAD_ALGO_OCB)) + strcat(dummy_string,"A2 "); + if (opt.flags.rfc4880bis && !openpgp_aead_test_algo (AEAD_ALGO_EAX)) + strcat(dummy_string,"A1 "); + if (personal) { /* The default internal hash algo order is: @@ -475,6 +489,11 @@ keygen_set_std_prefs (const char *string,int personal) if(set_one_pref(val,3,tok,zip,&nzip)) rc=-1; } + else if ((val=string_to_aead_algo (tok))) + { + if (set_one_pref (val, 4, tok, aead, &naead)) + rc = -1; + } else if (ascii_strcasecmp(tok,"mdc")==0) mdc=1; else if (ascii_strcasecmp(tok,"no-mdc")==0) @@ -520,6 +539,29 @@ keygen_set_std_prefs (const char *string,int personal) opt.personal_cipher_prefs[i].value = 0; } } + else if (personal == PREFTYPE_AEAD) + { + xfree(opt.personal_aead_prefs); + + if (!naead) + opt.personal_aead_prefs = NULL; + else + { + int i; + + opt.personal_aead_prefs= + xmalloc(sizeof(prefitem_t *)*(naead+1)); + + for (i=0; iref=1; - uid->prefs=xmalloc((sizeof(prefitem_t *)* - (nsym_prefs+nhash_prefs+nzip_prefs+1))); + uid->prefs = xmalloc ((sizeof(prefitem_t *)* + (nsym_prefs+naead_prefs+nhash_prefs+nzip_prefs+1))); for(i=0;iprefs[j].value=sym_prefs[i]; } + for (i=0; i < naead_prefs; i++, j++) + { + uid->prefs[j].type = PREFTYPE_AEAD; + uid->prefs[j].value = aead_prefs[i]; + } + for(i=0;iprefs[j].type=PREFTYPE_HASH; @@ -618,8 +669,9 @@ keygen_get_std_prefs(void) uid->prefs[j].type=PREFTYPE_NONE; uid->prefs[j].value=0; - uid->flags.mdc=mdc_available; - uid->flags.ks_modify=ks_modify; + uid->flags.mdc = mdc_available; + uid->flags.aead = aead_available; + uid->flags.ks_modify = ks_modify; return uid; } @@ -665,6 +717,49 @@ add_feature_mdc (PKT_signature *sig,int enabled) xfree (buf); } + +static void +add_feature_aead (PKT_signature *sig, int enabled) +{ + const byte *s; + size_t n; + int i; + char *buf; + + s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n ); + if (s && n && ((enabled && (s[0] & 0x02)) || (!enabled && !(s[0] & 0x02)))) + return; /* Already set or cleared */ + + if (!s || !n) + { /* Create a new one */ + n = 1; + buf = xmalloc_clear (n); + } + else + { + buf = xmalloc (n); + memcpy (buf, s, n); + } + + if (enabled) + buf[0] |= 0x02; /* AEAD supported */ + else + buf[0] &= ~0x02; + + /* Are there any bits set? */ + for (i=0; i < n; i++) + if (buf[i]) + break; + + if (i == n) + delete_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES); + else + build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n); + + xfree (buf); +} + + static void add_keyserver_modify (PKT_signature *sig,int enabled) { @@ -726,6 +821,14 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque) delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_SYM); } + if (naead_prefs) + build_sig_subpkt (sig, SIGSUBPKT_PREF_AEAD, aead_prefs, naead_prefs); + else + { + delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_AEAD); + delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_AEAD); + } + if (nhash_prefs) build_sig_subpkt (sig, SIGSUBPKT_PREF_HASH, hash_prefs, nhash_prefs); else @@ -744,6 +847,7 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque) /* Make sure that the MDC feature flag is set if needed. */ add_feature_mdc (sig,mdc_available); + add_feature_aead (sig, aead_available); add_keyserver_modify (sig,ks_modify); keygen_add_keyserver_url(sig,NULL); diff --git a/g10/main.h b/g10/main.h index 4a8f8c3..6abc598 100644 --- a/g10/main.h +++ b/g10/main.h @@ -41,6 +41,8 @@ # define DEFAULT_CIPHER_ALGO CIPHER_ALGO_3DES #endif +#define DEFAULT_AEAD_ALGO AEAD_ALGO_EAX + #define DEFAULT_DIGEST_ALGO ((GNUPG)? DIGEST_ALGO_SHA256:DIGEST_ALGO_SHA1) #define DEFAULT_S2K_DIGEST_ALGO DIGEST_ALGO_SHA1 #ifdef HAVE_ZIP @@ -123,6 +125,9 @@ int openpgp_cipher_blocklen (cipher_algo_t algo); int openpgp_cipher_test_algo(cipher_algo_t algo); const char *openpgp_cipher_algo_name (cipher_algo_t algo); +gpg_error_t openpgp_aead_test_algo (aead_algo_t algo); +const char *openpgp_aead_algo_name (aead_algo_t algo); + pubkey_algo_t map_pk_gcry_to_openpgp (enum gcry_pk_algos algo); int openpgp_pk_test_algo (pubkey_algo_t algo); int openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use); @@ -151,12 +156,14 @@ void obsolete_scdaemon_option (const char *configname, unsigned int configlineno, const char *name); int string_to_cipher_algo (const char *string); +aead_algo_t string_to_aead_algo (const char *string); int string_to_digest_algo (const char *string); const char *compress_algo_to_string(int algo); int string_to_compress_algo(const char *string); int check_compress_algo(int algo); int default_cipher_algo(void); +aead_algo_t default_aead_algo(void); int default_compress_algo(void); void compliance_failure(void); diff --git a/g10/misc.c b/g10/misc.c index 9016d27..2da0d27 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -582,6 +582,41 @@ openpgp_cipher_algo_name (cipher_algo_t algo) } +/* Return 0 if ALGO is supported. Return an error if not. */ +gpg_error_t +openpgp_aead_test_algo (aead_algo_t algo) +{ + switch (algo) + { + case AEAD_ALGO_NONE: + break; + case AEAD_ALGO_EAX: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + case AEAD_ALGO_OCB: + return 0; + } + + return gpg_error (GPG_ERR_INV_CIPHER_MODE); +} + + +/* Map the OpenPGP AEAD algorithm with ID ALGO to a string + * representation of the algorithm name. For unknown algorithm IDs + * this function returns "?". */ +const char * +openpgp_aead_algo_name (aead_algo_t algo) +{ + switch (algo) + { + case AEAD_ALGO_NONE: break; + case AEAD_ALGO_EAX: return "EAX"; + case AEAD_ALGO_OCB: return "OCB"; + } + + return "?"; +} + + /* Return 0 if ALGO is a supported OpenPGP public key algorithm. */ int openpgp_pk_test_algo (pubkey_algo_t algo) @@ -1112,6 +1147,39 @@ string_to_cipher_algo (const char *string) return val; } + +/* + * Map an AEAD mode string to a an AEAD algorithm number as defined by + * rrc4880bis. Also support the "An" syntax as used by the preference + * strings. + */ +aead_algo_t +string_to_aead_algo (const char *string) +{ + int result; + + if (!string) + result = 0; + if (!ascii_strcasecmp (string, "EAX")) + result = 1; + else if (!ascii_strcasecmp (string, "OCB")) + result = 2; + else if ((string[0]=='A' || string[0]=='a')) + { + char *endptr; + + string++; + result = strtol (string, &endptr, 10); + if (!*string || *endptr || result < 1 || result > 2) + result = 0; + } + else + result = 0; + + return result; +} + + /* * Wrapper around gcry_md_map_name to provide a fallback using the * "Hn" syntax as used by the preference strings. @@ -1228,6 +1296,18 @@ default_cipher_algo(void) return opt.s2k_cipher_algo; } + +aead_algo_t +default_aead_algo(void) +{ + if(opt.def_aead_algo) + return opt.def_aead_algo; + else if(opt.personal_aead_prefs) + return opt.personal_aead_prefs[0].value; + else + return DEFAULT_AEAD_ALGO; +} + /* There is no default_digest_algo function, but see sign.c:hash_for() */ diff --git a/g10/options.h b/g10/options.h index 61f7403..6ad1037 100644 --- a/g10/options.h +++ b/g10/options.h @@ -92,6 +92,7 @@ struct int no_armor; int list_packets; /* Option --list-packets active. */ int def_cipher_algo; + int def_aead_algo; int force_mdc; int disable_mdc; int def_digest_algo; @@ -177,6 +178,7 @@ struct const char *def_preference_list; const char *def_keyserver_url; prefitem_t *personal_cipher_prefs; + prefitem_t *personal_aead_prefs; prefitem_t *personal_digest_prefs; prefitem_t *personal_compress_prefs; struct weakhash *weak_digests; diff --git a/g10/packet.h b/g10/packet.h index 8dca88b..894b389 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -72,7 +72,8 @@ typedef enum { PREFTYPE_NONE = 0, PREFTYPE_SYM = 1, PREFTYPE_HASH = 2, - PREFTYPE_ZIP = 3 + PREFTYPE_ZIP = 3, + PREFTYPE_AEAD = 4 } preftype_t; typedef struct { @@ -290,6 +291,7 @@ typedef struct struct { unsigned int mdc:1; + unsigned int aead:1; unsigned int ks_modify:1; unsigned int compacted:1; unsigned int primary:2; /* 2 if set via the primary flag, 1 if calculated */ @@ -386,6 +388,7 @@ typedef struct struct { unsigned int mdc:1; /* MDC feature set. */ + unsigned int aead:1; /* AEAD feature set. */ unsigned int disabled_valid:1;/* The next flag is valid. */ unsigned int disabled:1; /* The key has been disabled. */ unsigned int primary:1; /* This is a primary key. */ @@ -471,7 +474,7 @@ typedef struct { Note: this is ignored when encrypting. */ byte is_partial; /* If 0, MDC is disabled. Otherwise, the MDC method that was used - (currently, only DIGEST_ALGO_SHA1 is supported). */ + (only DIGEST_ALGO_SHA1 has ever been defined). */ byte mdc_method; /* An iobuf holding the data to be decrypted. (This is not used for encryption!) */ diff --git a/g10/pkclist.c b/g10/pkclist.c index 581cae4..a759672 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -1468,9 +1468,12 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, support. All this doesn't mean IDEA is actually available, of course. */ implicit=CIPHER_ALGO_3DES; - break; + case PREFTYPE_AEAD: + /* No implicit algo. */ + break; + case PREFTYPE_HASH: /* While I am including this code for completeness, note that currently --pgp2 mode locks the hash at MD5, so this @@ -1553,6 +1556,8 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, prefs=NULL; if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs) prefs=opt.personal_cipher_prefs; + else if(preftype==PREFTYPE_AEAD && opt.personal_aead_prefs) + prefs=opt.personal_aead_prefs; else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs) prefs=opt.personal_digest_prefs; else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs) ----------------------------------------------------------------------- Summary of changes: common/openpgpdefs.h | 12 +++++- g10/Makefile.am | 1 + g10/cipher-aead.c | 67 ++++++++++++++++++++++++++++ g10/cipher.c | 7 +-- g10/dek.h | 25 ++++++++--- g10/encrypt.c | 90 ++++++++++++++++++++++++++++++++------ g10/filter.h | 8 +++- g10/getkey.c | 11 ++++- g10/gpg.c | 45 +++++++++++++++++++ g10/gpgcompose.c | 2 +- g10/kbnode.c | 5 ++- g10/keydb.h | 1 + g10/keyedit.c | 12 +++++- g10/keygen.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++---- g10/main.h | 8 ++++ g10/misc.c | 80 ++++++++++++++++++++++++++++++++++ g10/options.h | 3 ++ g10/packet.h | 7 ++- g10/pkclist.c | 32 +++++++++++++- g10/sign.c | 12 ++++-- 20 files changed, 502 insertions(+), 46 deletions(-) create mode 100644 g10/cipher-aead.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 10 21:33:21 2018 From: cvs at cvs.gnupg.org (by Robert J. Hansen) Date: Wed, 10 Jan 2018 21:33:21 +0100 Subject: [git] gnupg-doc - branch, master, updated. 43cbf5c1aeaa00e54f5bbbd7030a60fa881a2738 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 43cbf5c1aeaa00e54f5bbbd7030a60fa881a2738 (commit) from 7794c9fb38882b5e6d60226695887c804b9aaf62 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 43cbf5c1aeaa00e54f5bbbd7030a60fa881a2738 Author: Robert J. Hansen Date: Wed Jan 10 15:33:17 2018 -0500 Incorporate some changes from rms diff --git a/web/faq/gnupg-faq.org b/web/faq/gnupg-faq.org index b4fae61..25f8609 100644 --- a/web/faq/gnupg-faq.org +++ b/web/faq/gnupg-faq.org @@ -162,15 +162,23 @@ October 2017. :CUSTOM_ID: whats_gnupg :END: -GnuPG is cryptographic software that helps people ensure the -confidentiality, integrity and assurance of their data. Let?s try -that again: GnuPG is? +GnuPG is free cryptographic software from GNU which helps people +ensure the confidentiality, integrity and assurance of their +data. Let?s try that again: GnuPG is? +- /Free./ When we say ?free? we mean [[https://gnu.org/philosophy/free-sw.html][liberty, not price]]. You?re free + to use it, modify it, share it, tinker with it, and learn from it. + Software is meant to be used by people, and people deserve freedom. - /Cryptographic./ The word ?cryptography? is derived from two Greek words, ??????? (pronounced ?kryptos,? meaning ?hidden?) and ????? (pronounced ?graphein,? meaning ?writing?). Cryptography is the mathematical study of codes and ciphers. - /Software./ This one should already be obvious. +- /GNU./ GNU is a group that aims to give people the ability to do + all their computing with free software. Some groups have made + entire operating systems from it, but lots of GNU software will run + on proprietary systems, too ? although we encourage you to shift to + free ones if you can. - /Confidentiality./ No one except authorized parties should be able to read your data. - /Integrity./ It shouldn?t be possible to tamper with a message @@ -192,8 +200,9 @@ clients, such as Psi. :CUSTOM_ID: pronunciation :END: -?guh-NEW-pee-gee.? - +?GNU?, followed by the letters ?P? and ?G?. To learn how to pronounce +GNU, you may want to +[[https://www.gnu.org/gnu/pronunciation.en.html][listen to a recording]]. ** Is it compatible with Symantec?s PGP? :PROPERTIES: @@ -224,6 +233,7 @@ collectively as ?SHA-2?. PGP calls SHA-256 and SHA-512 by the non-standard names ?SHA-2-256? and ?SHA-2-512?, but they are the same algorithms. + ** Which operating systems does it run on? :PROPERTIES: :CUSTOM_ID: oses @@ -396,7 +406,6 @@ list?s archives. The [[https://bugs.gnupg.org/gnupg/][GnuPG project?s bug tracker]] is also publicly available. - * Where can I get more information? :PROPERTIES: :CUSTOM_ID: more_info ----------------------------------------------------------------------- Summary of changes: web/faq/gnupg-faq.org | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 11 13:32:43 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 11 Jan 2018 13:32:43 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-11-g17c6532 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 17c6532db77badd4111978b35b922ad6331d897b (commit) via 754a37dfc0076a01dd35cb1b62a3516631ba042e (commit) from 39f1abce90094bdbb03c38bb3aadf0db1d8147e6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 17c6532db77badd4111978b35b922ad6331d897b Author: Andre Heinecke Date: Thu Jan 11 13:30:28 2018 +0100 Increase Verbosity for issue3656 -- This turns up logging around the encryption. As this puts the full body of an encrypted mail in the debug log it should not be part of a release. GnuPG-Bug-Id: T3656 diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 88bac05..35d9c10 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -332,8 +332,8 @@ EVENT_SINK_INVOKE(MailItemEvents) If this encryption is successful and we pass the send as then the encrypted data is sent. */ - log_oom_extra ("%s:%s: Send : %p", - SRCNAME, __func__, m_mail); + log_debug ("%s:%s: Send : %p item %p", + SRCNAME, __func__, m_object, m_mail); if (!m_mail->needs_crypto ()) { log_debug ("%s:%s: No crypto neccessary. Passing send for unencrypted %p", @@ -349,6 +349,14 @@ EVENT_SINK_INVOKE(MailItemEvents) } m_mail->update_oom_data (); m_mail->set_needs_encrypt (true); + log_debug ("%s:%s: Send : %p item %p needs encrypt. Calling save.", + SRCNAME, __func__, m_mail, m_object); + log_debug ("%s:%s: Send : %p Setting uuid.", + SRCNAME, __func__, m_mail); + m_mail->set_uuid (); + log_debug ("%s:%s: Send : %p has subject: %s.", + SRCNAME, __func__, m_mail, m_mail->get_subject ().c_str()); + invoke_oom_method (m_object, "Save", NULL); if (m_mail->crypto_successful ()) { @@ -381,8 +389,9 @@ EVENT_SINK_INVOKE(MailItemEvents) log_debug ("%s:%s: Wipe succeded. %p.", SRCNAME, __func__, m_object); - log_debug ("%s:%s: Passing send event for message %p.", - SRCNAME, __func__, m_object); + const auto uuid = m_mail->get_uuid (); + log_debug ("%s:%s: Passing send event for message %p uuid: %s.", + SRCNAME, __func__, m_object, uuid.empty() ? "null" : uuid.c_str ()); break; } log_debug ("%s:%s: Cancel send for %p.", @@ -400,22 +409,22 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; return S_OK; } - log_debug ("%s:%s: Passing send event for message %p.", - SRCNAME, __func__, m_object); + log_debug ("%s:%s: Passing send event for encrypted message %p item %p.", + SRCNAME, __func__, m_object, m_mail); break; } else { - log_debug ("%s:%s: Message %p cancelling send - crypto failed.", - SRCNAME, __func__, m_object); + log_debug ("%s:%s: Message %p cancelling send - crypto failed item %p.", + SRCNAME, __func__, m_object, m_mail); *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } return S_OK; } case Write: { - log_oom_extra ("%s:%s: Write : %p", - SRCNAME, __func__, m_mail); + log_debug ("%s:%s: Write : %p", + SRCNAME, __func__, m_mail); /* This is a bit strange. We sometimes get multiple write events without a read in between. When we access the message in the second event it fails and if we cancel the event outlook @@ -454,20 +463,29 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } - log_debug ("%s:%s: Passing write event.", - SRCNAME, __func__); + const auto uuid = m_mail->get_uuid (); + log_debug ("%s:%s: Passing write event for message %p mailitem %p uuid: %s subject: %s", + SRCNAME, __func__, m_object, m_mail, uuid.empty() ? "null" : uuid.c_str (), + m_mail->get_subject ().c_str()); m_mail->set_needs_save (false); break; } case AfterWrite: { - log_oom_extra ("%s:%s: AfterWrite : %p", + log_debug ("%s:%s: AfterWrite : %p", SRCNAME, __func__, m_mail); if (m_mail->needs_encrypt ()) { + log_debug ("%s:%s: Mail needs encrypt: %p", + SRCNAME, __func__, m_mail); m_mail->encrypt_sign (); return S_OK; } + else + { + log_debug ("%s:%s: Mail does not need encrypt: %p", + SRCNAME, __func__, m_mail); + } break; } case Close: diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 057df95..0bf0637 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -86,6 +86,8 @@ sink_std_write (sink_t sink, const void *data, size_t datalen) if (!data) return 0; /* Flush - nothing to do here. */ + log_debug ("Sink write: %.*s", datalen, (char*)data); + hr = stream->Write(data, datalen, NULL); if (hr) { commit 754a37dfc0076a01dd35cb1b62a3516631ba042e Author: Andre Heinecke Date: Thu Jan 11 13:30:17 2018 +0100 Update NEWS -- diff --git a/NEWS b/NEWS index fa6a50f..828116d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,17 @@ -Noteworthy changes for version 2.0.6 (unreleased) +Noteworthy changes for version 2.0.6 (2018-01-11) ================================================= + * PGP/Inline sending is now compatible with Microsoft Exchange + Online. (T3662) + + * A bug that caused encrypted mails not to be displayed has been + fixed. (T3537) + + * A bug that caused drafted mails not to encrypt the correct + content has been fixed. (T3419) + + * The recipient lookup for Exchange addresses has been slightly + improved. Noteworthy changes for version 2.0.5 (2017-12-08) ================================================= ----------------------------------------------------------------------- Summary of changes: NEWS | 13 ++++++++++++- src/mailitem-events.cpp | 44 +++++++++++++++++++++++++++++++------------- src/mimemaker.cpp | 2 ++ 3 files changed, 45 insertions(+), 14 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 11 13:45:00 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 11 Jan 2018 13:45:00 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-12-ga6eeeaa Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via a6eeeaaa902a80aec50fe3fbc42f09683a8b4f36 (commit) from 17c6532db77badd4111978b35b922ad6331d897b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a6eeeaaa902a80aec50fe3fbc42f09683a8b4f36 Author: Andre Heinecke Date: Thu Jan 11 13:44:26 2018 +0100 Fix w64 build * src/mimemaker.cpp (sink_std_write): Fix format for x64 diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 0bf0637..17b64d4 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -86,7 +86,7 @@ sink_std_write (sink_t sink, const void *data, size_t datalen) if (!data) return 0; /* Flush - nothing to do here. */ - log_debug ("Sink write: %.*s", datalen, (char*)data); + log_debug ("Sink write: %.*s", (int)datalen, (char*)data); hr = stream->Write(data, datalen, NULL); if (hr) ----------------------------------------------------------------------- Summary of changes: src/mimemaker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 11 16:47:51 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 11 Jan 2018 16:47:51 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-14-g707250c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 707250ce6151a504f9143776cec2d6f09f4a80e4 (commit) via 090e2a0cb2fffad534544119604bfa454e90c016 (commit) from a6eeeaaa902a80aec50fe3fbc42f09683a8b4f36 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 707250ce6151a504f9143776cec2d6f09f4a80e4 Author: Andre Heinecke Date: Thu Jan 11 16:40:31 2018 +0100 Add special sauce for Outlook S/MIME code interact * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Check if after encryption msgclass is not gpgol on MAPI Message and activate Hack if otherwise. * src/windowmessage.cpp (delayed_close, CLOSE): New. * src/windowmessage.h: Update Accordingly. -- If somehow S/MIME is involved in Outlook, even if the S/MIME sign button is just toggled and untoggled, Outlook changes behavior. When that happened Send would send the plain text mail instead of the encrypted mail. Now this here is very much experimental programming: When the S/MIME Code is somehow involved the Message in MAPI (not the base message) is not correctly updated and shows the original IPM.Note message class. We detect that now. If that happens we use super low level MAPI to submit our constructed base message and then cancel the send / close the composer. GnuPG-Bug-Id: T3656 diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 88bac05..8d42e81 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -23,6 +23,7 @@ #include "eventsink.h" #include "eventsinks.h" #include "mymapi.h" +#include "mymapitags.h" #include "oomhelp.h" #include "ocidl.h" #include "windowmessages.h" @@ -336,8 +337,8 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__, m_mail); if (!m_mail->needs_crypto ()) { - log_debug ("%s:%s: No crypto neccessary. Passing send for unencrypted %p", - SRCNAME, __func__, m_mail); + log_debug ("%s:%s: No crypto neccessary. Passing send for %p obj %p", + SRCNAME, __func__, m_mail, m_object); break; } @@ -349,6 +350,7 @@ EVENT_SINK_INVOKE(MailItemEvents) } m_mail->update_oom_data (); m_mail->set_needs_encrypt (true); + invoke_oom_method (m_object, "Save", NULL); if (m_mail->crypto_successful ()) { @@ -376,29 +378,75 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } - if (!m_mail->wipe (true)) + if (m_mail->wipe (true)) { - log_debug ("%s:%s: Wipe succeded. %p.", - SRCNAME, __func__, m_object); - - log_debug ("%s:%s: Passing send event for message %p.", + log_debug ("%s:%s: Cancel send for %p.", SRCNAME, __func__, m_object); + wchar_t *title = utf8_to_wchar (_("GpgOL: Encryption not possible!")); + wchar_t *msg = utf8_to_wchar (_( + "Outlook returned an error when trying to send the encrypted mail.\n\n" + "Please restart Outlook and try again.\n\n" + "If it still fails consider using an encrypted attachment or\n" + "switching to PGP/Inline in GpgOL's options.")); + MessageBoxW (get_active_hwnd(), msg, title, + MB_ICONERROR | MB_OK); + xfree (msg); + xfree (title); + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + return S_OK; + } + { + /* Now we adress T3656 if Outlooks internal S/MIME is somehow + * mixed in (even if it is enabled and then disabled) it might + * cause strange behavior in that it sends the plain message + * and not the encrypted message. Tests have shown that we can + * bypass that by calling submit message on our base + * message. + * + * We do this conditionally as our other way of using OOM + * to send is proven to work and we don't want to mess + * with it. + */ + // Get the Message class. + HRESULT hr; + LPSPropValue propval = NULL; + + LPMESSAGE message = get_oom_message (m_object); + hr = HrGetOneProp ((LPMAPIPROP)message, PR_MESSAGE_CLASS_A, &propval); + gpgol_release (message); + if (FAILED (hr)) + { + log_error ("%s:%s: HrGetOneProp() failed: hr=%#lx\n", + SRCNAME, __func__, hr); + gpgol_release (message); + break; + } + if (propval->Value.lpszA && !strstr (propval->Value.lpszA, "GpgOL")) + { + // Does not have a message class by us. + log_debug ("%s:%s: Message %p - No GpgOL Message class after encryption.", + SRCNAME, __func__, m_object); + log_debug ("%s:%s: Message %p - Activating T3656 Workaround", + SRCNAME, __func__, m_object); + message = get_oom_base_message (m_object); + mapi_save_changes (message, KEEP_OPEN_READWRITE | FORCE_SAVE); + message->SubmitMessage(0); + gpgol_release (message); + + // Cancel send + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + + // Close the composer and trigger unloads + CloseHandle(CreateThread (NULL, 0, close_mail, (LPVOID) m_mail, 0, + NULL)); + } + MAPIFreeBuffer (propval); + } + + if (*(parms->rgvarg[0].pboolVal) == VARIANT_TRUE) + { break; } - log_debug ("%s:%s: Cancel send for %p.", - SRCNAME, __func__, m_object); - wchar_t *title = utf8_to_wchar (_("GpgOL: Encryption not possible!")); - wchar_t *msg = utf8_to_wchar (_( - "Outlook returned an error when trying to send the encrypted mail.\n\n" - "Please restart Outlook and try again.\n\n" - "If it still fails consider using an encrypted attachment or\n" - "switching to PGP/Inline in GpgOL's options.")); - MessageBoxW (get_active_hwnd(), msg, title, - MB_ICONERROR | MB_OK); - xfree (msg); - xfree (title); - *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; - return S_OK; } log_debug ("%s:%s: Passing send event for message %p.", SRCNAME, __func__, m_object); @@ -454,6 +502,8 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } + log_debug ("%s:%s: Passing write event. Subject: %s Body: %s MsgCls: %s", + SRCNAME, __func__, m_mail->get_subject().c_str(), m_mail->get_body().c_str(), get_oom_string (m_object, "MessageClass")); log_debug ("%s:%s: Passing write event.", SRCNAME, __func__); m_mail->set_needs_save (false); diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 1259496..f44b9df 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -76,6 +76,18 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SRCNAME, __func__); break; } + case (CLOSE): + { + auto mail = (Mail*) ctx->data; + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: Close for mail which is gone.", + SRCNAME, __func__); + break; + } + Mail::close (mail); + break; + } default: log_debug ("Unknown msg"); } @@ -255,3 +267,10 @@ delayed_invalidate_ui (LPVOID) gpgrt_lock_unlock(&invalidate_lock); return 0; } + +DWORD WINAPI +close_mail (LPVOID mail) +{ + do_in_ui_thread (CLOSE, mail); + return 0; +} diff --git a/src/windowmessages.h b/src/windowmessages.h index cc1cb62..f53ecd4 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -42,6 +42,7 @@ typedef enum _gpgol_wmsg_type to the mail object. */ RECIPIENT_ADDED = 3, /* A recipient was added. Data should be ptr to mail */ + CLOSE = 4, /* Send the message in the next event loop. */ } gpgol_wmsg_type; typedef struct @@ -73,6 +74,9 @@ create_message_hook(); DWORD WINAPI delayed_invalidate_ui (LPVOID); +DWORD WINAPI +close_mail (LPVOID); + void add_explorer (LPDISPATCH explorer); void remove_explorer (LPDISPATCH explorer); commit 090e2a0cb2fffad534544119604bfa454e90c016 Author: Andre Heinecke Date: Thu Jan 11 14:25:33 2018 +0100 Revert increased verbosity for T3656 -- The bug is now reproducable. It depends on Outlooks S/MIME settings. diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 35d9c10..88bac05 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -332,8 +332,8 @@ EVENT_SINK_INVOKE(MailItemEvents) If this encryption is successful and we pass the send as then the encrypted data is sent. */ - log_debug ("%s:%s: Send : %p item %p", - SRCNAME, __func__, m_object, m_mail); + log_oom_extra ("%s:%s: Send : %p", + SRCNAME, __func__, m_mail); if (!m_mail->needs_crypto ()) { log_debug ("%s:%s: No crypto neccessary. Passing send for unencrypted %p", @@ -349,14 +349,6 @@ EVENT_SINK_INVOKE(MailItemEvents) } m_mail->update_oom_data (); m_mail->set_needs_encrypt (true); - log_debug ("%s:%s: Send : %p item %p needs encrypt. Calling save.", - SRCNAME, __func__, m_mail, m_object); - log_debug ("%s:%s: Send : %p Setting uuid.", - SRCNAME, __func__, m_mail); - m_mail->set_uuid (); - log_debug ("%s:%s: Send : %p has subject: %s.", - SRCNAME, __func__, m_mail, m_mail->get_subject ().c_str()); - invoke_oom_method (m_object, "Save", NULL); if (m_mail->crypto_successful ()) { @@ -389,9 +381,8 @@ EVENT_SINK_INVOKE(MailItemEvents) log_debug ("%s:%s: Wipe succeded. %p.", SRCNAME, __func__, m_object); - const auto uuid = m_mail->get_uuid (); - log_debug ("%s:%s: Passing send event for message %p uuid: %s.", - SRCNAME, __func__, m_object, uuid.empty() ? "null" : uuid.c_str ()); + log_debug ("%s:%s: Passing send event for message %p.", + SRCNAME, __func__, m_object); break; } log_debug ("%s:%s: Cancel send for %p.", @@ -409,22 +400,22 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; return S_OK; } - log_debug ("%s:%s: Passing send event for encrypted message %p item %p.", - SRCNAME, __func__, m_object, m_mail); + log_debug ("%s:%s: Passing send event for message %p.", + SRCNAME, __func__, m_object); break; } else { - log_debug ("%s:%s: Message %p cancelling send - crypto failed item %p.", - SRCNAME, __func__, m_object, m_mail); + log_debug ("%s:%s: Message %p cancelling send - crypto failed.", + SRCNAME, __func__, m_object); *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } return S_OK; } case Write: { - log_debug ("%s:%s: Write : %p", - SRCNAME, __func__, m_mail); + log_oom_extra ("%s:%s: Write : %p", + SRCNAME, __func__, m_mail); /* This is a bit strange. We sometimes get multiple write events without a read in between. When we access the message in the second event it fails and if we cancel the event outlook @@ -463,29 +454,20 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } - const auto uuid = m_mail->get_uuid (); - log_debug ("%s:%s: Passing write event for message %p mailitem %p uuid: %s subject: %s", - SRCNAME, __func__, m_object, m_mail, uuid.empty() ? "null" : uuid.c_str (), - m_mail->get_subject ().c_str()); + log_debug ("%s:%s: Passing write event.", + SRCNAME, __func__); m_mail->set_needs_save (false); break; } case AfterWrite: { - log_debug ("%s:%s: AfterWrite : %p", + log_oom_extra ("%s:%s: AfterWrite : %p", SRCNAME, __func__, m_mail); if (m_mail->needs_encrypt ()) { - log_debug ("%s:%s: Mail needs encrypt: %p", - SRCNAME, __func__, m_mail); m_mail->encrypt_sign (); return S_OK; } - else - { - log_debug ("%s:%s: Mail does not need encrypt: %p", - SRCNAME, __func__, m_mail); - } break; } case Close: diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 17b64d4..057df95 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -86,8 +86,6 @@ sink_std_write (sink_t sink, const void *data, size_t datalen) if (!data) return 0; /* Flush - nothing to do here. */ - log_debug ("Sink write: %.*s", (int)datalen, (char*)data); - hr = stream->Write(data, datalen, NULL); if (hr) { ----------------------------------------------------------------------- Summary of changes: src/mailitem-events.cpp | 130 ++++++++++++++++++++++++++++++------------------ src/mimemaker.cpp | 2 - src/windowmessages.cpp | 19 +++++++ src/windowmessages.h | 4 ++ 4 files changed, 104 insertions(+), 51 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 11 16:53:29 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 11 Jan 2018 16:53:29 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-15-g7d772b3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 7d772b3e6cadd73c23080b51d29d6a297ea59c67 (commit) from 707250ce6151a504f9143776cec2d6f09f4a80e4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7d772b3e6cadd73c23080b51d29d6a297ea59c67 Author: Andre Heinecke Date: Thu Jan 11 16:53:01 2018 +0100 Add cmt to clarify base / non base msg usage -- diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 8d42e81..b3161f0 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -411,6 +411,7 @@ EVENT_SINK_INVOKE(MailItemEvents) HRESULT hr; LPSPropValue propval = NULL; + // It's important we use the _not_ base message here. LPMESSAGE message = get_oom_message (m_object); hr = HrGetOneProp ((LPMAPIPROP)message, PR_MESSAGE_CLASS_A, &propval); gpgol_release (message); @@ -429,6 +430,7 @@ EVENT_SINK_INVOKE(MailItemEvents) log_debug ("%s:%s: Message %p - Activating T3656 Workaround", SRCNAME, __func__, m_object); message = get_oom_base_message (m_object); + // It's important we use the _base_ message here. mapi_save_changes (message, KEEP_OPEN_READWRITE | FORCE_SAVE); message->SubmitMessage(0); gpgol_release (message); ----------------------------------------------------------------------- Summary of changes: src/mailitem-events.cpp | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 12 03:13:47 2018 From: cvs at cvs.gnupg.org (by Robert J. Hansen) Date: Fri, 12 Jan 2018 03:13:47 +0100 Subject: [git] gnupg-doc - branch, master, updated. 3fe91c68480c1c11a66b7a9931450f5f9c9e3701 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 3fe91c68480c1c11a66b7a9931450f5f9c9e3701 (commit) from 43cbf5c1aeaa00e54f5bbbd7030a60fa881a2738 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3fe91c68480c1c11a66b7a9931450f5f9c9e3701 Author: Robert J. Hansen Date: Thu Jan 11 21:13:42 2018 -0500 Final changes from rms diff --git a/web/faq/gnupg-faq.org b/web/faq/gnupg-faq.org index 25f8609..8850eea 100644 --- a/web/faq/gnupg-faq.org +++ b/web/faq/gnupg-faq.org @@ -162,8 +162,8 @@ October 2017. :CUSTOM_ID: whats_gnupg :END: -GnuPG is free cryptographic software from GNU which helps people -ensure the confidentiality, integrity and assurance of their +GnuPG is free cryptographic software from the GNU Project which helps +people ensure the confidentiality, integrity and assurance of their data. Let?s try that again: GnuPG is? - /Free./ When we say ?free? we mean [[https://gnu.org/philosophy/free-sw.html][liberty, not price]]. You?re free @@ -174,11 +174,8 @@ data. Let?s try that again: GnuPG is? (pronounced ?graphein,? meaning ?writing?). Cryptography is the mathematical study of codes and ciphers. - /Software./ This one should already be obvious. -- /GNU./ GNU is a group that aims to give people the ability to do - all their computing with free software. Some groups have made - entire operating systems from it, but lots of GNU software will run - on proprietary systems, too ? although we encourage you to shift to - free ones if you can. +- /GNU Project./ The [[https://www.gnu.org][GNU Project]] is a group that aims to give people + the ability to do all their computing with free software. - /Confidentiality./ No one except authorized parties should be able to read your data. - /Integrity./ It shouldn?t be possible to tamper with a message @@ -204,6 +201,7 @@ clients, such as Psi. GNU, you may want to [[https://www.gnu.org/gnu/pronunciation.en.html][listen to a recording]]. + ** Is it compatible with Symantec?s PGP? :PROPERTIES: :CUSTOM_ID: compatible @@ -382,10 +380,13 @@ lot of the software industry does not your freedom to use the software for any purpose, your freedom to study and learn from how it works, your freedom to share it with others who might benefit from it, and more. Free Software is the antithesis of -this: Free Software is meant to respect your rights. You may use the +this: Free Software is meant to respect your freedoms. You may use the software for any purpose: you may inspect and modify the source code: you may share the software and/or your modifications with others. +GnuPG works with many operating systems, including ones that don?t +respect your freedoms. If you?d like to make the shift to a free +operating system, [[https://www.gnu.org/distros/free-distros.html][you have many choices]]. ** How can I donate money to the GnuPG project? :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: web/faq/gnupg-faq.org | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 12 08:14:36 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Jan 2018 08:14:36 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-9-g6fb5713 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 6fb5713f4a6976900cc70c140e61043b6ef688d1 (commit) from 339b3301ee8410fe3bbdebb66a6e83801d79d40d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6fb5713f4a6976900cc70c140e61043b6ef688d1 Author: Andre Heinecke Date: Mon Jan 8 19:09:28 2018 +0100 doc: Note pinentry-mode for passphrase opts * doc/gpg.texi (--passphrase, --passphrase-file, --passphrase-fd): Note that pinentry-mode needs to be loopback. Signed-off-by: Andre Heinecke diff --git a/doc/gpg.texi b/doc/gpg.texi index 35bb9a8..9776a3b 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3082,8 +3082,9 @@ will be read from file descriptor @var{n}. If you use 0 for @var{n}, the passphrase will be read from STDIN. This can only be used if only one passphrase is supplied. -Note that this passphrase is only used if the option @option{--batch} -has also been given. This is different from GnuPG version 1.x. +Note that since Version 2.0 this passphrase is only used if the +option @option{--batch} has also been given. Since Version 2.1 +the @option{--pinentry-mode} also needs to be set to @code{loopback}. @item --passphrase-file @var{file} @opindex passphrase-file @@ -3092,8 +3093,10 @@ be read from file @var{file}. This can only be used if only one passphrase is supplied. Obviously, a passphrase stored in a file is of questionable security if other users can read this file. Don't use this option if you can avoid it. -Note that this passphrase is only used if the option @option{--batch} -has also been given. This is different from GnuPG version 1.x. + +Note that since Version 2.0 this passphrase is only used if the +option @option{--batch} has also been given. Since Version 2.1 +the @option{--pinentry-mode} also needs to be set to @code{loopback}. @item --passphrase @var{string} @opindex passphrase @@ -3101,8 +3104,10 @@ Use @var{string} as the passphrase. This can only be used if only one passphrase is supplied. Obviously, this is of very questionable security on a multi-user system. Don't use this option if you can avoid it. -Note that this passphrase is only used if the option @option{--batch} -has also been given. This is different from GnuPG version 1.x. + +Note that since Version 2.0 this passphrase is only used if the +option @option{--batch} has also been given. Since Version 2.1 +the @option{--pinentry-mode} also needs to be set to @code{loopback}. @item --pinentry-mode @var{mode} @opindex pinentry-mode ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 12 10:39:04 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Jan 2018 10:39:04 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-16-ge7ef14e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via e7ef14e076f9e4364e940c8e9e27591cf90a0986 (commit) from 7d772b3e6cadd73c23080b51d29d6a297ea59c67 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e7ef14e076f9e4364e940c8e9e27591cf90a0986 Author: Andre Heinecke Date: Fri Jan 12 10:37:20 2018 +0100 Fix multipart signed mails * src/mimemaker.cpp (add_body_and_attachments): Add extra line for multipart/related and multipart/alternative. -- Outlook adds that line when the message is constructed. If that line is not part of our hashed message we will create an invalid signature. GnuPG-Bug-Id: T3736 diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 057df95..53e6049 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -1422,6 +1422,7 @@ add_body_and_attachments (sink_t sink, LPMESSAGE message, if ((rc=write_multistring (sink, "Content-Type: multipart/related;\r\n", "\tboundary=\"", outer_boundary, "\"\r\n", + "\r\n", /* <--- Outlook adds an extra line. */ NULL))) return rc; } @@ -1431,6 +1432,7 @@ add_body_and_attachments (sink_t sink, LPMESSAGE message, if ((rc=write_multistring (sink, "Content-Type: multipart/mixed;\r\n", "\tboundary=\"", outer_boundary, "\"\r\n", + "\r\n", /* <--- Outlook adds an extra line. */ NULL))) return rc; } @@ -1448,6 +1450,7 @@ add_body_and_attachments (sink_t sink, LPMESSAGE message, if ((rc=write_multistring (sink, "Content-Type: multipart/related;\r\n", "\tboundary=\"", inner_boundary, "\"\r\n", + "\r\n", /* <--- Outlook adds an extra line. */ NULL))) { return rc; ----------------------------------------------------------------------- Summary of changes: src/mimemaker.cpp | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 12 10:51:42 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Jan 2018 10:51:42 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.5-17-g94b84de Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 94b84de77b8dac262c70981c30defa43668f71f2 (commit) from e7ef14e076f9e4364e940c8e9e27591cf90a0986 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 94b84de77b8dac262c70981c30defa43668f71f2 Author: Andre Heinecke Date: Fri Jan 12 10:50:39 2018 +0100 Update NEWS -- diff --git a/NEWS b/NEWS index 828116d..9779f9e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Noteworthy changes for version 2.0.6 (2018-01-11) +Noteworthy changes for version 2.0.6 (2018-01-12) ================================================= * PGP/Inline sending is now compatible with Microsoft Exchange @@ -13,6 +13,11 @@ Noteworthy changes for version 2.0.6 (2018-01-11) * The recipient lookup for Exchange addresses has been slightly improved. + * When Outlooks internal S/MIME handling code was activated + mails might be sent out unencrypted (T3656) + + * Fixed signed only PGP Mails with attachments. (T3735) + Noteworthy changes for version 2.0.5 (2017-12-08) ================================================= ----------------------------------------------------------------------- Summary of changes: NEWS | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 12 11:11:49 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Jan 2018 11:11:49 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.0.6-1-g7341d64 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 7341d641165effc57f6a6e38f7405f7be8e1926f (commit) from 94b84de77b8dac262c70981c30defa43668f71f2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7341d641165effc57f6a6e38f7405f7be8e1926f Author: Andre Heinecke Date: Fri Jan 12 11:11:25 2018 +0100 Post release version bump * po: Auto update. diff --git a/NEWS b/NEWS index 9779f9e..c885f95 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Noteworthy changes for version 2.0.7 (unreleased) +================================================= + + + Noteworthy changes for version 2.0.6 (2018-01-12) ================================================= diff --git a/configure.ac b/configure.ac index 0e3f02d..009860d 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ min_automake_version="1.14" # (git tag -s gpgol-k.n.m) and run "./autogen.sh --force". Please # bump the version number immediately *after* the release and do # another commit and push so that the git magic is able to work. -m4_define([mym4_version], [2.0.6]) +m4_define([mym4_version], [2.0.7]) # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a diff --git a/po/de.po b/po/de.po index 4ca6b60..be41a1b 100644 --- a/po/de.po +++ b/po/de.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.0.0\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2017-12-08 10:21+0100\n" +"POT-Creation-Date: 2018-01-12 10:52+0100\n" "PO-Revision-Date: 2017-12-08 06:55+0100\n" "Last-Translator: Andre Heinecke \n" "Language-Team: English \n" @@ -77,7 +77,7 @@ msgstr "Die Benutzeroberfl?che zu ?ndern erfordert einen Neustart von Outlook" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:300 +#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:301 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -174,11 +174,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "M?chten Sie diesen Ordner von GpgOL befreien?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1626 src/mail.cpp:1697 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1642 src/mail.cpp:1713 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Verschl?sselte Nachricht" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1627 src/mail.cpp:1698 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1643 src/mail.cpp:1714 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Vertraute Absenderadresse" @@ -382,7 +382,7 @@ msgstr "" "Dies ist eine verschl?sselte Nachricht.\n" "Klicken Sie hier um weitere Informationen zu erhalten. " -#: src/mail.cpp:344 +#: src/mail.cpp:352 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" @@ -392,7 +392,7 @@ msgstr "" "Die unsignierten / unverschl?sselten Anh?nge sind:\n" "\n" -#: src/mail.cpp:349 +#: src/mail.cpp:357 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" @@ -402,7 +402,7 @@ msgstr "" "Die unsignierten Anh?nge sind:\n" "\n" -#: src/mail.cpp:354 +#: src/mail.cpp:362 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" @@ -412,7 +412,7 @@ msgstr "" "Die unverschl?sselten Anh?nge sind:\n" "\n" -#: src/mail.cpp:394 +#: src/mail.cpp:402 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." @@ -420,23 +420,23 @@ msgstr "" "Note: Die Anh?nge k?nnten auf Dateiebene verschl?sselt oder singiert sein, " "aber GpgOL kann deren Kryptostatus nicht anzeigen." -#: src/mail.cpp:397 +#: src/mail.cpp:405 msgid "GpgOL Warning" msgstr "GpgOL Warnung" -#: src/mail.cpp:753 src/mail.cpp:1941 +#: src/mail.cpp:763 src/mail.cpp:1957 msgid "Encrypted message" msgstr "Verschl?sselte Nachricht" -#: src/mail.cpp:754 +#: src/mail.cpp:764 msgid "Please wait while the message is being decrypted / verified..." msgstr "Bitte warten Sie w?hrend die Nachricht entschl?sselt / gepr?ft wird..." -#: src/mail.cpp:1002 +#: src/mail.cpp:1012 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "GpgOL: Oops, G Suite Sync Konto erkannt" -#: src/mail.cpp:1006 +#: src/mail.cpp:1016 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -449,7 +449,7 @@ msgstr "" "\n" "Details siehe: https://dev.gnupg.org/T3545" -#: src/mail.cpp:1021 +#: src/mail.cpp:1031 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -462,7 +462,7 @@ msgstr "" "\n" "Details siehe: https://dev.gnupg.org/T3545" -#: src/mail.cpp:1036 +#: src/mail.cpp:1046 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -479,93 +479,93 @@ msgstr "" "\n" "M?chten Sie die Nachricht nur verschl?sseln?" -#: src/mail.cpp:1886 +#: src/mail.cpp:1902 msgid "Security Level 4" msgstr "Sicherheit Stufe 4" -#: src/mail.cpp:1890 +#: src/mail.cpp:1906 msgid "Trust Level 4" msgstr "Vertrauen Stufe 4" -#: src/mail.cpp:1894 +#: src/mail.cpp:1910 msgid "Security Level 3" msgstr "Sicherheit Stufe 3" -#: src/mail.cpp:1898 +#: src/mail.cpp:1914 msgid "Trust Level 3" msgstr "Vertrauen Stufe 3" -#: src/mail.cpp:1902 +#: src/mail.cpp:1918 msgid "Security Level 2" msgstr "Sicherheit Stufe 2" -#: src/mail.cpp:1906 +#: src/mail.cpp:1922 msgid "Trust Level 2" msgstr "Vertrauen Stufe 2" -#: src/mail.cpp:1910 +#: src/mail.cpp:1926 msgid "Encrypted" msgstr "Verschl?sselt" -#: src/mail.cpp:1919 src/mail.cpp:1921 src/ribbon-callbacks.cpp:1604 +#: src/mail.cpp:1935 src/mail.cpp:1937 src/ribbon-callbacks.cpp:1604 msgid "Insecure" msgstr "Unsicher" -#: src/mail.cpp:1933 +#: src/mail.cpp:1949 msgid "Signed and encrypted message" msgstr "Signierte und verschl?sselte Nachricht" -#: src/mail.cpp:1937 +#: src/mail.cpp:1953 msgid "Signed message" msgstr "Signierte Nachricht" -#: src/mail.cpp:1944 src/ribbon-callbacks.cpp:1627 +#: src/mail.cpp:1960 src/ribbon-callbacks.cpp:1627 msgid "Insecure message" msgstr "Unsichere Nachricht" -#: src/mail.cpp:1955 src/mail.cpp:1966 +#: src/mail.cpp:1971 src/mail.cpp:1982 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "Sie k?nnen nicht sicher sein wer die Nachricht gesendet, modifiziert oder " "w?hrend der ?bertragung gelesen hat." -#: src/mail.cpp:1958 +#: src/mail.cpp:1974 msgid "The message was signed but the verification failed with:" msgstr "Die Nachricht ist signiert aber die ?berpr?fung schlug fehl mit:" -#: src/mail.cpp:1976 +#: src/mail.cpp:1992 msgid "The encryption was VS-NfD-compliant." msgstr "Diese Verschl?sselung war VS-NfD-konform." -#: src/mail.cpp:1980 +#: src/mail.cpp:1996 msgid "The encryption was not VS-NfD-compliant." msgstr "Diese Verschl?sselung war nicht VS-NfD-konform." -#: src/mail.cpp:1984 +#: src/mail.cpp:2000 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "Aber Sie k?nnen nicht sicher sein wer der Absender der Nachricht ist da " "diese nicht signiert wurde. " -#: src/mail.cpp:2007 +#: src/mail.cpp:2023 msgid "You signed this message." msgstr "Sie haben diese Nachricht signiert." -#: src/mail.cpp:2011 +#: src/mail.cpp:2027 msgid "The senders identity was certified by yourself." msgstr "Die Idenit?t des Absenders wurde von ihnen selbst beglaubigt." -#: src/mail.cpp:2015 +#: src/mail.cpp:2031 msgid "The sender is allowed to certify identities for you." msgstr "Der Absender ist berechtigt f?r Sie Identit?ten zu beglaubigen." -#: src/mail.cpp:2028 +#: src/mail.cpp:2044 msgid "The senders identity was certified by several trusted people." msgstr "" "Die Identit?t des Absenders wurde von mehreren vertrauensw?rdigen Personen " "beglaubigt." -#: src/mail.cpp:2033 +#: src/mail.cpp:2049 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -574,12 +574,12 @@ msgstr "" "Die Idenit?t des Absenders wurde best?tigt von:\n" "'%s'\n" -#: src/mail.cpp:2041 +#: src/mail.cpp:2057 msgid "Some trusted people have certified the senders identity." msgstr "" "Einige vertrauensw?rde Personen haben die Identit?t des Absenders beglaubigt." -#: src/mail.cpp:2051 +#: src/mail.cpp:2067 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -591,11 +591,11 @@ msgstr "" "Seit %s haben Sie %i Nachrichten an diesen Absender verschl?sselt und %i " "Signaturen gepr?ft." -#: src/mail.cpp:2067 +#: src/mail.cpp:2083 msgid "The senders signature was verified for the first time." msgstr "The Signatur des Absenders wurde das erste mal verifiziert." -#: src/mail.cpp:2074 +#: src/mail.cpp:2090 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -605,70 +605,70 @@ msgstr "" "Nachrichten von diesem absender verifziert und %i Nachrichten verschl?ssel " "haben. Seit dem %s." -#: src/mail.cpp:2088 +#: src/mail.cpp:2104 msgid "But the sender address is not trustworthy because:" msgstr "Aber die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2089 +#: src/mail.cpp:2105 msgid "The sender address is not trustworthy because:" msgstr "Die Absenderadresse ist nicht vertrauensw?rdig da:" -#: src/mail.cpp:2097 +#: src/mail.cpp:2113 msgid "The signature is invalid: \n" msgstr "Die Signatur ist ung?ltig: \n" -#: src/mail.cpp:2102 +#: src/mail.cpp:2118 msgid "There was an error verifying the signature.\n" msgstr "Beim ?berpr?fen der Signatur ist ein Fehler aufgetreten.\n" -#: src/mail.cpp:2106 +#: src/mail.cpp:2122 msgid "The signature is expired.\n" msgstr "Die Signatur ist abgelaufen.\n" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used key" msgstr "Der verwendete Schl?ssel" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used certificate" msgstr "Das verwendete Zertifikat" -#: src/mail.cpp:2118 +#: src/mail.cpp:2134 msgid "is not available." msgstr "ist nicht verf?gbar." -#: src/mail.cpp:2122 +#: src/mail.cpp:2138 msgid "is revoked." msgstr "wurde zur?ckgezogen." -#: src/mail.cpp:2126 +#: src/mail.cpp:2142 msgid "is expired." msgstr "ist veraltet. " -#: src/mail.cpp:2130 +#: src/mail.cpp:2146 msgid "is not meant for signing." msgstr "ist nicht zum signieren vorgesehen. " -#: src/mail.cpp:2134 src/mail.cpp:2138 +#: src/mail.cpp:2150 src/mail.cpp:2154 msgid "could not be checked for revocation." msgstr "wurde m?glicherweise zur?ckgezogen." -#: src/mail.cpp:2143 +#: src/mail.cpp:2159 msgid "is not the same as the key that was used for this address in the past." msgstr "" "ist nicht der gleiche Schl?ssel der in der vergangenheit f?r diese Adresse " "verwendet wurde." -#: src/mail.cpp:2149 +#: src/mail.cpp:2165 #, c-format msgid "does not claim the address: \"%s\"." msgstr "passt nicht zu der mailaddresse: \"%s\". " -#: src/mail.cpp:2162 +#: src/mail.cpp:2178 msgid "is not certified by any trustworthy key." msgstr "wurde von keinem vertrauensw?rdigen Schl?ssel beglaubigt." -#: src/mail.cpp:2166 +#: src/mail.cpp:2182 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -676,49 +676,49 @@ msgstr "" "wurde von keiner vertrauensw?rdigen Zertifizierungsstelle beglaubigt oder " "die Zertifizierungsstelle ist unbekannt." -#: src/mail.cpp:2171 +#: src/mail.cpp:2187 msgid "The sender marked this address as revoked." msgstr "Der Absender hat diese Adresse zur?ckgezogen." -#: src/mail.cpp:2175 +#: src/mail.cpp:2191 msgid "is marked as not trustworthy." msgstr "ist als nicht vertrauensw?rdig markiert." -#: src/mail.cpp:2185 +#: src/mail.cpp:2201 msgid "The signature is VS-NfD-compliant." msgstr "Die Signatur ist VS-NfD-konform." -#: src/mail.cpp:2189 +#: src/mail.cpp:2205 msgid "The signature is not VS-NfD-compliant." msgstr "Die Signatur ist nicht VS-NfD-konform." -#: src/mail.cpp:2197 +#: src/mail.cpp:2213 msgid "The encryption is VS-NfD-compliant." msgstr "Diese Verschl?sselung ist VS-NfD-konform." -#: src/mail.cpp:2201 +#: src/mail.cpp:2217 msgid "The encryption is not VS-NfD-compliant." msgstr "Diese Verschl?sselung ist nicht VS-NfD-konform." -#: src/mail.cpp:2212 +#: src/mail.cpp:2228 msgid "Click here to change the key used for this address." msgstr "Klicken Sie hier um den Schl?ssel f?r diese Adresse zu ?ndern." -#: src/mail.cpp:2216 +#: src/mail.cpp:2232 msgid "Click here for details about the key." msgstr "Klicken Sie hier f?r Details zu dem Schl?ssel" -#: src/mail.cpp:2217 +#: src/mail.cpp:2233 msgid "Click here for details about the certificate." msgstr "Klicken Sie hier f?r Details zu dem Zertifiakt." -#: src/mail.cpp:2221 +#: src/mail.cpp:2237 msgid "Click here to search the key on the configured keyserver." msgstr "" "Klicken Sie hier um den Schl?ssel auf dem konfigurierten Schl?sselserver zu " "suchen. " -#: src/mail.cpp:2222 +#: src/mail.cpp:2238 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Klicken Sie hier um das Zertifikat auf dem konfigurierten X509 " @@ -735,11 +735,11 @@ msgstr "" "Sie sicher, da? lediglich das Text Format ausgew?hlt wurde.\n" "(In der Men?leiste: \"Format\" => \"Nur Text\")" -#: src/mailitem-events.cpp:292 +#: src/mailitem-events.cpp:295 msgid "Sorry, that's not possible, yet" msgstr "Sorry, dies ist leider noch nicht m?glich" -#: src/mailitem-events.cpp:294 +#: src/mailitem-events.cpp:297 #, c-format msgid "" "GpgOL has prevented the change to the \"%s\" property.\n" @@ -761,11 +761,11 @@ msgstr "" "Beispielsweise durch einen Rechtsklick auf die Nachricht wenn diese nicht " "ausgew?hlt ist.\n" -#: src/mailitem-events.cpp:380 +#: src/mailitem-events.cpp:385 msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Verschl?sselung nicht m?glich!" -#: src/mailitem-events.cpp:382 +#: src/mailitem-events.cpp:387 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -786,11 +786,11 @@ msgstr "" msgid "Note: Using compatibility flags: %s" msgstr "Notiz: Diese Kompatibilit?tsflags werden verwendet: %s" -#: src/mapihelp.cpp:1786 src/mapihelp.cpp:1794 src/mapihelp.cpp:1802 +#: src/mapihelp.cpp:1807 src/mapihelp.cpp:1815 src/mapihelp.cpp:1823 msgid "[no subject]" msgstr "[Kein Betreff]" -#: src/mapihelp.cpp:2427 +#: src/mapihelp.cpp:2448 msgid "" "[The content of this message is not visible because it has been decrypted by " "another Outlook session. Use the \"decrypt/verify\" command to make it " @@ -800,7 +800,7 @@ msgstr "" "Outlook Sitzung entschl?sselt wurde. Verwenden Sie den Men?punkt " "\"entschl?sseln/?berpr?fen\" um den Inhalt wieder sichtbar zu machen.]" -#: src/mapihelp.cpp:3310 +#: src/mapihelp.cpp:3331 msgid "" "[The content of this message is not visible due to an processing error in " "GpgOL.]" @@ -808,13 +808,13 @@ msgstr "" "[Aufgrund eines Verarbeitungsfehlers in GpgOL ist der Inhalt dieser " "Nachricht nicht sichtbar.]" -#: src/message.cpp:178 +#: src/message.cpp:179 msgid "[Crypto operation failed - can't show the body of the message]" msgstr "" "[Krypto-Operation ist fehlgeschlagen - Der Text der Nachricht kann nicht " "angezeigt werden.]" -#: src/message.cpp:280 +#: src/message.cpp:281 #, c-format msgid "" "Signature status: %s\n" @@ -827,22 +827,22 @@ msgstr "" "Struktur der Nachricht :\n" "%s" -#: src/message.cpp:288 +#: src/message.cpp:289 msgid "GpgOL - Message Information" msgstr "GpgOL - Informationen zu der Nachricht" -#: src/message.cpp:520 +#: src/message.cpp:521 msgid "Signature verification of an encrypted message is not possible." msgstr "" "Die Pr?fung der Signatur ist bei einer verschl?sselten Nachrichten nicht " "m?glich." -#: src/message.cpp:531 +#: src/message.cpp:532 msgid "Signature verification of this message class is not possible." msgstr "" "Die Pr?fung der Signatur ist bei dieser Nachrichtenklasse nicht m?glich." -#: src/message.cpp:534 +#: src/message.cpp:535 msgid "" "Signature verification of this S/MIME message is not possible. Please check " "that S/MIME processing has been enabled." @@ -851,15 +851,15 @@ msgstr "" "Bitte ?berpr?fen Sie in den Einstellungen, da? die Verarbeitung von S/MIME " "eingeschaltet ist." -#: src/message.cpp:538 +#: src/message.cpp:539 msgid "This message has no signature." msgstr "Diese Nachricht hat keine Signatur." -#: src/message.cpp:706 +#: src/message.cpp:707 msgid "This message is not encrypted." msgstr "Diese Nachricht ist nicht verschl?sselt." -#: src/message.cpp:933 +#: src/message.cpp:934 #, c-format msgid "" "Decryption failed\n" @@ -868,20 +868,20 @@ msgstr "" "Entschl?sselungsfehler\n" "(%s)" -#: src/message.cpp:1094 +#: src/message.cpp:1105 msgid "No recipients to encrypt to are given" msgstr "Empf?nger zum Verschl?sseln wurde nicht angegeben" -#: src/message.cpp:1109 src/message.cpp:1136 +#: src/message.cpp:1120 src/message.cpp:1147 msgid "Encrypting or signing an empty message is not possible." msgstr "Eine leere Nachricht kann nicht signiert oder verschl?sselt werden." -#: src/message.cpp:1117 +#: src/message.cpp:1128 #, c-format msgid "Encryption failed (%s)" msgstr "Verschl?sselungsfehler (%s)" -#: src/message.cpp:1145 +#: src/message.cpp:1156 #, c-format msgid "Signing failed (%s)" msgstr "Signaturerstellungsfehler (%s)" diff --git a/po/fr.po b/po/fr.po index 904db18..97007c3 100644 --- a/po/fr.po +++ b/po/fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2017-12-08 10:21+0100\n" +"POT-Creation-Date: 2018-01-12 10:52+0100\n" "PO-Revision-Date: 2015-10-01 17:05+0200\n" "Last-Translator: Olivier Serve \n" "Language-Team: French \n" @@ -75,7 +75,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:300 +#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:301 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -171,12 +171,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Voulez-vous r?cup?rer ce dossier ?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1626 src/mail.cpp:1697 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1642 src/mail.cpp:1713 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "D?chiffrer le message" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1627 src/mail.cpp:1698 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1643 src/mail.cpp:1714 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -377,51 +377,51 @@ msgstr "" "Ceci est un message chiffr?.\n" "Veuillez le s?lectionner pour plus d'informations." -#: src/mail.cpp:344 +#: src/mail.cpp:352 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:349 +#: src/mail.cpp:357 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:354 +#: src/mail.cpp:362 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:394 +#: src/mail.cpp:402 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:397 +#: src/mail.cpp:405 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:753 src/mail.cpp:1941 +#: src/mail.cpp:763 src/mail.cpp:1957 #, fuzzy msgid "Encrypted message" msgstr "D?chiffrer le message" -#: src/mail.cpp:754 +#: src/mail.cpp:764 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1002 +#: src/mail.cpp:1012 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1006 +#: src/mail.cpp:1016 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -429,7 +429,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1021 +#: src/mail.cpp:1031 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -437,7 +437,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1036 +#: src/mail.cpp:1046 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -447,105 +447,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:1886 +#: src/mail.cpp:1902 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1890 +#: src/mail.cpp:1906 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1894 +#: src/mail.cpp:1910 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1898 +#: src/mail.cpp:1914 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1902 +#: src/mail.cpp:1918 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1906 +#: src/mail.cpp:1922 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1910 +#: src/mail.cpp:1926 #, fuzzy msgid "Encrypted" msgstr "Chiffrer" -#: src/mail.cpp:1919 src/mail.cpp:1921 src/ribbon-callbacks.cpp:1604 +#: src/mail.cpp:1935 src/mail.cpp:1937 src/ribbon-callbacks.cpp:1604 msgid "Insecure" msgstr "" -#: src/mail.cpp:1933 +#: src/mail.cpp:1949 #, fuzzy msgid "Signed and encrypted message" msgstr "D?chiffrer le message" -#: src/mail.cpp:1937 +#: src/mail.cpp:1953 #, fuzzy msgid "Signed message" msgstr "D?chiffrer le message" -#: src/mail.cpp:1944 src/ribbon-callbacks.cpp:1627 +#: src/mail.cpp:1960 src/ribbon-callbacks.cpp:1627 #, fuzzy msgid "Insecure message" msgstr "D?chiffrer le message" -#: src/mail.cpp:1955 src/mail.cpp:1966 +#: src/mail.cpp:1971 src/mail.cpp:1982 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1958 +#: src/mail.cpp:1974 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:1976 +#: src/mail.cpp:1992 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:1980 +#: src/mail.cpp:1996 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:1984 +#: src/mail.cpp:2000 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:2023 #, fuzzy msgid "You signed this message." msgstr "D?chiffrer le message" -#: src/mail.cpp:2011 +#: src/mail.cpp:2027 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:2031 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2028 +#: src/mail.cpp:2044 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2049 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2057 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2051 +#: src/mail.cpp:2067 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -553,133 +553,133 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2083 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2074 +#: src/mail.cpp:2090 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2088 +#: src/mail.cpp:2104 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2089 +#: src/mail.cpp:2105 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2097 +#: src/mail.cpp:2113 #, fuzzy msgid "The signature is invalid: \n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2102 +#: src/mail.cpp:2118 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2122 #, fuzzy msgid "The signature is expired.\n" msgstr "Cette signature est valide\n" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used key" msgstr "" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 #, fuzzy msgid "The used certificate" msgstr "Erreur de v?rification" -#: src/mail.cpp:2118 +#: src/mail.cpp:2134 #, fuzzy msgid "is not available." msgstr "La liste de r?vocation (CRL) n'est pas disponible\n" -#: src/mail.cpp:2122 +#: src/mail.cpp:2138 msgid "is revoked." msgstr "" -#: src/mail.cpp:2126 +#: src/mail.cpp:2142 msgid "is expired." msgstr "" -#: src/mail.cpp:2130 +#: src/mail.cpp:2146 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2134 src/mail.cpp:2138 +#: src/mail.cpp:2150 src/mail.cpp:2154 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2143 +#: src/mail.cpp:2159 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2149 +#: src/mail.cpp:2165 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2178 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2166 +#: src/mail.cpp:2182 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2187 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2191 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2185 +#: src/mail.cpp:2201 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2189 +#: src/mail.cpp:2205 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2197 +#: src/mail.cpp:2213 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2201 +#: src/mail.cpp:2217 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Cette signature est valide\n" -#: src/mail.cpp:2212 +#: src/mail.cpp:2228 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2216 +#: src/mail.cpp:2232 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2217 +#: src/mail.cpp:2233 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2221 +#: src/mail.cpp:2237 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2222 +#: src/mail.cpp:2238 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" @@ -693,11 +693,11 @@ msgstr "" "et non des messages RTF. Merci de v?rifier que seul le format texte\n" "a ?t? s?lectionn?." -#: src/mailitem-events.cpp:292 +#: src/mailitem-events.cpp:295 msgid "Sorry, that's not possible, yet" msgstr "" -#: src/mailitem-events.cpp:294 +#: src/mailitem-events.cpp:297 #, c-format msgid "" "GpgOL has prevented the change to the \"%s\" property.\n" @@ -709,12 +709,12 @@ msgid "" "For example by right clicking but not selecting the message.\n" msgstr "" -#: src/mailitem-events.cpp:380 +#: src/mailitem-events.cpp:385 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "D?chiffrer le message" -#: src/mailitem-events.cpp:382 +#: src/mailitem-events.cpp:387 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -729,11 +729,11 @@ msgstr "" msgid "Note: Using compatibility flags: %s" msgstr "Note?: Utilisation de marqueurs de compatibilit??: %s" -#: src/mapihelp.cpp:1786 src/mapihelp.cpp:1794 src/mapihelp.cpp:1802 +#: src/mapihelp.cpp:1807 src/mapihelp.cpp:1815 src/mapihelp.cpp:1823 msgid "[no subject]" msgstr "[pas de sujet]" -#: src/mapihelp.cpp:2427 +#: src/mapihelp.cpp:2448 msgid "" "[The content of this message is not visible because it has been decrypted by " "another Outlook session. Use the \"decrypt/verify\" command to make it " @@ -743,7 +743,7 @@ msgstr "" "autre session Outlook. Utiliser la commande \"d?chiffrer/v?rifier\" afin de " "le rendre visible]" -#: src/mapihelp.cpp:3310 +#: src/mapihelp.cpp:3331 msgid "" "[The content of this message is not visible due to an processing error in " "GpgOL.]" @@ -751,13 +751,13 @@ msgstr "" "[Le contenu de ce message n'est pas visible ? cause d'une erreur d'ex?cution " "de GpgOL.]" -#: src/message.cpp:178 +#: src/message.cpp:179 msgid "[Crypto operation failed - can't show the body of the message]" msgstr "" "[?chec de l'op?ration cryptographique - impossible de visualiser le corps du " "message]" -#: src/message.cpp:280 +#: src/message.cpp:281 #, c-format msgid "" "Signature status: %s\n" @@ -770,19 +770,19 @@ msgstr "" "Structure MIME?: \n" "%s" -#: src/message.cpp:288 +#: src/message.cpp:289 msgid "GpgOL - Message Information" msgstr "GgpOL - Message d'information" -#: src/message.cpp:520 +#: src/message.cpp:521 msgid "Signature verification of an encrypted message is not possible." msgstr "Il n'est pas possible de v?rifier la signature d'un message chiffr?." -#: src/message.cpp:531 +#: src/message.cpp:532 msgid "Signature verification of this message class is not possible." msgstr "Il n'est pas possible de v?rifier la signature de ce type de message." -#: src/message.cpp:534 +#: src/message.cpp:535 msgid "" "Signature verification of this S/MIME message is not possible. Please check " "that S/MIME processing has been enabled." @@ -790,15 +790,15 @@ msgstr "" "Il n'est pas possible de v?rifier la signature S/MIME de ce message. " "Veuillez v?rifier que le traitement S/MIME a ?t? activ?." -#: src/message.cpp:538 +#: src/message.cpp:539 msgid "This message has no signature." msgstr "Ce message n'a pas de signature." -#: src/message.cpp:706 +#: src/message.cpp:707 msgid "This message is not encrypted." msgstr "Ce message n'est pas chiffr?" -#: src/message.cpp:933 +#: src/message.cpp:934 #, c-format msgid "" "Decryption failed\n" @@ -807,20 +807,20 @@ msgstr "" "?chec du d?chiffrement\n" "(%s)" -#: src/message.cpp:1094 +#: src/message.cpp:1105 msgid "No recipients to encrypt to are given" msgstr "Il n'y a pas de destinataires vers qui chiffrer" -#: src/message.cpp:1109 src/message.cpp:1136 +#: src/message.cpp:1120 src/message.cpp:1147 msgid "Encrypting or signing an empty message is not possible." msgstr "Il n'est pas possible de chiffrer ou signer un message vide." -#: src/message.cpp:1117 +#: src/message.cpp:1128 #, c-format msgid "Encryption failed (%s)" msgstr "?chec du chiffrement (%s)" -#: src/message.cpp:1145 +#: src/message.cpp:1156 #, c-format msgid "Signing failed (%s)" msgstr "?chec de la signature (%s)" diff --git a/po/pt.po b/po/pt.po index 7a86af1..d6a0317 100644 --- a/po/pt.po +++ b/po/pt.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL 1.1.1\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2017-12-08 10:21+0100\n" +"POT-Creation-Date: 2018-01-12 10:52+0100\n" "PO-Revision-Date: 2017-10-16 14:17+0100\n" "Last-Translator: Marco A.G.Pinto \n" "Language-Team: Portuguese \n" @@ -78,7 +78,7 @@ msgstr "Mudar a interface necessita reiniciar o Outlook." #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:300 +#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:301 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -174,11 +174,11 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "Queres reverter esta pasta?" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1626 src/mail.cpp:1697 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1642 src/mail.cpp:1713 msgid "GpgOL: Encrypted Message" msgstr "GpgOL: Mensagem Encriptada" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1627 src/mail.cpp:1698 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1643 src/mail.cpp:1714 msgid "GpgOL: Trusted Sender Address" msgstr "GpgOL: Endere?o de Remetente Confi?vel" @@ -382,7 +382,7 @@ msgstr "" "Esta ? uma mensagem encriptada.\n" "Clica para mais informa??o. " -#: src/mail.cpp:344 +#: src/mail.cpp:352 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" @@ -392,7 +392,7 @@ msgstr "" "Os anexos n?o-assinados / n?o-encriptados s?o:\n" "\n" -#: src/mail.cpp:349 +#: src/mail.cpp:357 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" @@ -402,7 +402,7 @@ msgstr "" "Os anexos n?o-assinados s?o:\n" "\n" -#: src/mail.cpp:354 +#: src/mail.cpp:362 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" @@ -412,7 +412,7 @@ msgstr "" "Os anexos n?o-encriptados s?o:\n" "\n" -#: src/mail.cpp:394 +#: src/mail.cpp:402 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." @@ -420,25 +420,25 @@ msgstr "" "Nota: Os anexos podem ser encriptados ou assinados ao n?vel de ficheiro, mas " "o status do GpgOL n?o se aplica a eles." -#: src/mail.cpp:397 +#: src/mail.cpp:405 msgid "GpgOL Warning" msgstr "Aviso do GpgOL" -#: src/mail.cpp:753 src/mail.cpp:1941 +#: src/mail.cpp:763 src/mail.cpp:1957 msgid "Encrypted message" msgstr "Mensagem encriptada" -#: src/mail.cpp:754 +#: src/mail.cpp:764 msgid "Please wait while the message is being decrypted / verified..." msgstr "" "Por favor aguarda enquanto a mensagem est? a ser desencriptada / " "verificada..." -#: src/mail.cpp:1002 +#: src/mail.cpp:1012 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1006 +#: src/mail.cpp:1016 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -446,7 +446,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1021 +#: src/mail.cpp:1031 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -454,7 +454,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1036 +#: src/mail.cpp:1046 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -464,91 +464,91 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:1886 +#: src/mail.cpp:1902 msgid "Security Level 4" msgstr "N?vel de seguran?a 4" -#: src/mail.cpp:1890 +#: src/mail.cpp:1906 msgid "Trust Level 4" msgstr "N?vel de Confian?a 4" -#: src/mail.cpp:1894 +#: src/mail.cpp:1910 msgid "Security Level 3" msgstr "N?vel de Seguran?a 3" -#: src/mail.cpp:1898 +#: src/mail.cpp:1914 msgid "Trust Level 3" msgstr "N?vel de Confian?a 3" -#: src/mail.cpp:1902 +#: src/mail.cpp:1918 msgid "Security Level 2" msgstr "N?vel de Seguran?a 2" -#: src/mail.cpp:1906 +#: src/mail.cpp:1922 msgid "Trust Level 2" msgstr "N?vel de Confian?a 2" -#: src/mail.cpp:1910 +#: src/mail.cpp:1926 msgid "Encrypted" msgstr "Encriptada" -#: src/mail.cpp:1919 src/mail.cpp:1921 src/ribbon-callbacks.cpp:1604 +#: src/mail.cpp:1935 src/mail.cpp:1937 src/ribbon-callbacks.cpp:1604 msgid "Insecure" msgstr "Insegura" -#: src/mail.cpp:1933 +#: src/mail.cpp:1949 msgid "Signed and encrypted message" msgstr "Mensagem assinada e encriptada" -#: src/mail.cpp:1937 +#: src/mail.cpp:1953 msgid "Signed message" msgstr "Mensagem assinada" -#: src/mail.cpp:1944 src/ribbon-callbacks.cpp:1627 +#: src/mail.cpp:1960 src/ribbon-callbacks.cpp:1627 msgid "Insecure message" msgstr "Mensagem insegura" -#: src/mail.cpp:1955 src/mail.cpp:1966 +#: src/mail.cpp:1971 src/mail.cpp:1982 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" "N?o podes ter a certeza de quem enviou, modificou e leu a mensagem em " "tr?nsito." -#: src/mail.cpp:1958 +#: src/mail.cpp:1974 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:1976 +#: src/mail.cpp:1992 msgid "The encryption was VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:1980 +#: src/mail.cpp:1996 msgid "The encryption was not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:1984 +#: src/mail.cpp:2000 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" "N?o podes ter certeza de quem enviou a mensagem, porque n?o est? assinada." -#: src/mail.cpp:2007 +#: src/mail.cpp:2023 msgid "You signed this message." msgstr "Assinaste esta mensagem." -#: src/mail.cpp:2011 +#: src/mail.cpp:2027 msgid "The senders identity was certified by yourself." msgstr "A identidade dos remetentes foi certificada por ti pr?prio." -#: src/mail.cpp:2015 +#: src/mail.cpp:2031 msgid "The sender is allowed to certify identities for you." msgstr "O remetente pode certificar identidades para ti." -#: src/mail.cpp:2028 +#: src/mail.cpp:2044 msgid "The senders identity was certified by several trusted people." msgstr "" "A identidade dos remetentes foi certificada por v?rias pessoas confi?veis." -#: src/mail.cpp:2033 +#: src/mail.cpp:2049 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" @@ -557,11 +557,11 @@ msgstr "" "A identidade dos remetentes ? certificada pelo emissor confi?vel:\n" "'%s'\n" -#: src/mail.cpp:2041 +#: src/mail.cpp:2057 msgid "Some trusted people have certified the senders identity." msgstr "Algumas pessoas confi?veis certificaram a identidade dos remetentes." -#: src/mail.cpp:2051 +#: src/mail.cpp:2067 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -572,11 +572,11 @@ msgstr "" "comunica??o com este endere?o desde %s.\n" "Encriptaste %i e verificaste %i mensagens desde ent?o." -#: src/mail.cpp:2067 +#: src/mail.cpp:2083 msgid "The senders signature was verified for the first time." msgstr "A assinatura dos remetentes foi verificada pela primeira vez." -#: src/mail.cpp:2074 +#: src/mail.cpp:2090 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " @@ -585,68 +585,68 @@ msgstr "" "O endere?o dos remetentes ainda n?o ? confi?vel porque apenas verificaste %i " "mensagens e encriptaste %i mensagens a eles desde %s." -#: src/mail.cpp:2088 +#: src/mail.cpp:2104 msgid "But the sender address is not trustworthy because:" msgstr "Mas o endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2089 +#: src/mail.cpp:2105 msgid "The sender address is not trustworthy because:" msgstr "O endere?o do remetente n?o ? confi?vel porque:" -#: src/mail.cpp:2097 +#: src/mail.cpp:2113 msgid "The signature is invalid: \n" msgstr "A assinatura ? inv?lida: \n" -#: src/mail.cpp:2102 +#: src/mail.cpp:2118 msgid "There was an error verifying the signature.\n" msgstr "Houve um erro ao verificar a assinatura.\n" -#: src/mail.cpp:2106 +#: src/mail.cpp:2122 msgid "The signature is expired.\n" msgstr "A assinatura expirou.\n" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used key" msgstr "A chave usada" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used certificate" msgstr "O certificado usado" -#: src/mail.cpp:2118 +#: src/mail.cpp:2134 msgid "is not available." msgstr "n?o est? dispon?vel." -#: src/mail.cpp:2122 +#: src/mail.cpp:2138 msgid "is revoked." msgstr "est? revogado." -#: src/mail.cpp:2126 +#: src/mail.cpp:2142 msgid "is expired." msgstr "expirou." -#: src/mail.cpp:2130 +#: src/mail.cpp:2146 msgid "is not meant for signing." msgstr "n?o ? destinado a assinar." -#: src/mail.cpp:2134 src/mail.cpp:2138 +#: src/mail.cpp:2150 src/mail.cpp:2154 msgid "could not be checked for revocation." msgstr "n?o pode ser verificado para revoga??o." -#: src/mail.cpp:2143 +#: src/mail.cpp:2159 msgid "is not the same as the key that was used for this address in the past." msgstr "n?o ? o mesmo que a chave usada para este endere?o no passado." -#: src/mail.cpp:2149 +#: src/mail.cpp:2165 #, c-format msgid "does not claim the address: \"%s\"." msgstr "n?o reivindica o endere?o: \"%s\"." -#: src/mail.cpp:2162 +#: src/mail.cpp:2178 msgid "is not certified by any trustworthy key." msgstr "n?o est? certificado por qualquer chave confi?vel." -#: src/mail.cpp:2166 +#: src/mail.cpp:2182 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." @@ -654,47 +654,47 @@ msgstr "" "n?o est? certificado por uma Autoridade de Certifica??o confi?vel ou a " "Autoridade de Certifica??o ? desconhecida." -#: src/mail.cpp:2171 +#: src/mail.cpp:2187 msgid "The sender marked this address as revoked." msgstr "O remetente marcou este endere?o como revogado." -#: src/mail.cpp:2175 +#: src/mail.cpp:2191 msgid "is marked as not trustworthy." msgstr "est? marcado como n?o confi?vel." -#: src/mail.cpp:2185 +#: src/mail.cpp:2201 msgid "The signature is VS-NfD-compliant." msgstr "A assinatura est? em conformidade com VS-NfD." -#: src/mail.cpp:2189 +#: src/mail.cpp:2205 msgid "The signature is not VS-NfD-compliant." msgstr "A assinatura n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2197 +#: src/mail.cpp:2213 msgid "The encryption is VS-NfD-compliant." msgstr "A encripta??o est? em conformidade com VS-NfD." -#: src/mail.cpp:2201 +#: src/mail.cpp:2217 msgid "The encryption is not VS-NfD-compliant." msgstr "A encripta??o n?o est? em conformidade com VS-NfD." -#: src/mail.cpp:2212 +#: src/mail.cpp:2228 msgid "Click here to change the key used for this address." msgstr "Clica aqui para alterar a chave usada para este endere?o." -#: src/mail.cpp:2216 +#: src/mail.cpp:2232 msgid "Click here for details about the key." msgstr "Clica aqui para obter detalhes sobre a chave." -#: src/mail.cpp:2217 +#: src/mail.cpp:2233 msgid "Click here for details about the certificate." msgstr "Clica aqui para obter detalhes sobre o certificado." -#: src/mail.cpp:2221 +#: src/mail.cpp:2237 msgid "Click here to search the key on the configured keyserver." msgstr "Clica aqui para localizar a chave no servidor de chaves configurado." -#: src/mail.cpp:2222 +#: src/mail.cpp:2238 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" "Clica aqui para localizar o certificado no servidor de chaves X509 " @@ -710,11 +710,11 @@ msgstr "" "n?o mensagens RTF. Por favor certifica-te que apenas o formato\n" "de texto foi selecionado." -#: src/mailitem-events.cpp:292 +#: src/mailitem-events.cpp:295 msgid "Sorry, that's not possible, yet" msgstr "Desculpa, isso n?o ? poss?vel, ainda" -#: src/mailitem-events.cpp:294 +#: src/mailitem-events.cpp:297 #, c-format msgid "" "GpgOL has prevented the change to the \"%s\" property.\n" @@ -736,12 +736,12 @@ msgstr "" "Por exemplo, ao clicar com o bot?o direito do rato, mas n?o selecionar a " "mensagem.\n" -#: src/mailitem-events.cpp:380 +#: src/mailitem-events.cpp:385 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "GpgOL: Mensagem Encriptada" -#: src/mailitem-events.cpp:382 +#: src/mailitem-events.cpp:387 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -756,11 +756,11 @@ msgstr "" msgid "Note: Using compatibility flags: %s" msgstr "Nota: A usar sinalizadores de compatibilidade: %s" -#: src/mapihelp.cpp:1786 src/mapihelp.cpp:1794 src/mapihelp.cpp:1802 +#: src/mapihelp.cpp:1807 src/mapihelp.cpp:1815 src/mapihelp.cpp:1823 msgid "[no subject]" msgstr "[sem assunto]" -#: src/mapihelp.cpp:2427 +#: src/mapihelp.cpp:2448 msgid "" "[The content of this message is not visible because it has been decrypted by " "another Outlook session. Use the \"decrypt/verify\" command to make it " @@ -770,7 +770,7 @@ msgstr "" "sess?o do Outlook. Usa o comando \"desencriptar/verificar\" para torn?-lo " "vis?vel]" -#: src/mapihelp.cpp:3310 +#: src/mapihelp.cpp:3331 msgid "" "[The content of this message is not visible due to an processing error in " "GpgOL.]" @@ -778,13 +778,13 @@ msgstr "" "[O conte?do desta mensagem n?o ? vis?vel devido a um erro de processamento " "no GpgOL.]" -#: src/message.cpp:178 +#: src/message.cpp:179 msgid "[Crypto operation failed - can't show the body of the message]" msgstr "" "[A opera??o criptogr?fica falhou - n?o ? poss?vel mostrar o corpo da " "mensagem]" -#: src/message.cpp:280 +#: src/message.cpp:281 #, c-format msgid "" "Signature status: %s\n" @@ -797,19 +797,19 @@ msgstr "" "Estrutura MIME .:\n" "%s" -#: src/message.cpp:288 +#: src/message.cpp:289 msgid "GpgOL - Message Information" msgstr "GpgOL - Informa??o da Mensagem" -#: src/message.cpp:520 +#: src/message.cpp:521 msgid "Signature verification of an encrypted message is not possible." msgstr "A verifica??o da assinatura de uma mensagem encriptada n?o ? poss?vel." -#: src/message.cpp:531 +#: src/message.cpp:532 msgid "Signature verification of this message class is not possible." msgstr "A verifica??o da assinatura desta classe de mensagem n?o ? poss?vel." -#: src/message.cpp:534 +#: src/message.cpp:535 msgid "" "Signature verification of this S/MIME message is not possible. Please check " "that S/MIME processing has been enabled." @@ -817,15 +817,15 @@ msgstr "" "A verifica??o da assinatura desta mensagem S/MIME n?o ? poss?vel. Por favor " "verifica se o processamento S/MIME foi ativado." -#: src/message.cpp:538 +#: src/message.cpp:539 msgid "This message has no signature." msgstr "Esta mensagem n?o tem assinatura." -#: src/message.cpp:706 +#: src/message.cpp:707 msgid "This message is not encrypted." msgstr "Esta mensagem n?o est? encriptada." -#: src/message.cpp:933 +#: src/message.cpp:934 #, c-format msgid "" "Decryption failed\n" @@ -834,20 +834,20 @@ msgstr "" "A desencripta??o falhou\n" "(%s)" -#: src/message.cpp:1094 +#: src/message.cpp:1105 msgid "No recipients to encrypt to are given" msgstr "N?o foram selecionados destinat?rios para a encripta??o" -#: src/message.cpp:1109 src/message.cpp:1136 +#: src/message.cpp:1120 src/message.cpp:1147 msgid "Encrypting or signing an empty message is not possible." msgstr "Encriptar ou assinar uma mensagem em branco n?o ? poss?vel." -#: src/message.cpp:1117 +#: src/message.cpp:1128 #, c-format msgid "Encryption failed (%s)" msgstr "A encripta??o falhou (%s)" -#: src/message.cpp:1145 +#: src/message.cpp:1156 #, c-format msgid "Signing failed (%s)" msgstr "A assinatura falhou (%s)" diff --git a/po/sv.po b/po/sv.po index 0eeae5b..a39ae9c 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GPGol\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2017-12-08 10:21+0100\n" +"POT-Creation-Date: 2018-01-12 10:52+0100\n" "PO-Revision-Date: 2006-12-12 23:52+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -75,7 +75,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:300 +#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:301 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -163,12 +163,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1626 src/mail.cpp:1697 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1642 src/mail.cpp:1713 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "Dekryptera och validera meddelandet." -#: src/gpgoladdin.cpp:447 src/mail.cpp:1627 src/mail.cpp:1698 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1643 src/mail.cpp:1714 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -366,51 +366,51 @@ msgid "" "Click for more information. " msgstr "" -#: src/mail.cpp:344 +#: src/mail.cpp:352 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:349 +#: src/mail.cpp:357 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:354 +#: src/mail.cpp:362 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:394 +#: src/mail.cpp:402 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:397 +#: src/mail.cpp:405 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:753 src/mail.cpp:1941 +#: src/mail.cpp:763 src/mail.cpp:1957 #, fuzzy msgid "Encrypted message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:754 +#: src/mail.cpp:764 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1002 +#: src/mail.cpp:1012 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1006 +#: src/mail.cpp:1016 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -418,7 +418,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1021 +#: src/mail.cpp:1031 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -426,7 +426,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1036 +#: src/mail.cpp:1046 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -436,105 +436,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:1886 +#: src/mail.cpp:1902 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1890 +#: src/mail.cpp:1906 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1894 +#: src/mail.cpp:1910 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1898 +#: src/mail.cpp:1914 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1902 +#: src/mail.cpp:1918 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1906 +#: src/mail.cpp:1922 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1910 +#: src/mail.cpp:1926 #, fuzzy msgid "Encrypted" msgstr "Kryptering" -#: src/mail.cpp:1919 src/mail.cpp:1921 src/ribbon-callbacks.cpp:1604 +#: src/mail.cpp:1935 src/mail.cpp:1937 src/ribbon-callbacks.cpp:1604 msgid "Insecure" msgstr "" -#: src/mail.cpp:1933 +#: src/mail.cpp:1949 #, fuzzy msgid "Signed and encrypted message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:1937 +#: src/mail.cpp:1953 #, fuzzy msgid "Signed message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:1944 src/ribbon-callbacks.cpp:1627 +#: src/mail.cpp:1960 src/ribbon-callbacks.cpp:1627 #, fuzzy msgid "Insecure message" msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:1955 src/mail.cpp:1966 +#: src/mail.cpp:1971 src/mail.cpp:1982 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1958 +#: src/mail.cpp:1974 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:1976 +#: src/mail.cpp:1992 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:1980 +#: src/mail.cpp:1996 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:1984 +#: src/mail.cpp:2000 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:2023 #, fuzzy msgid "You signed this message." msgstr "Dekryptera och validera meddelandet." -#: src/mail.cpp:2011 +#: src/mail.cpp:2027 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:2031 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2028 +#: src/mail.cpp:2044 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2049 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2057 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2051 +#: src/mail.cpp:2067 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -542,133 +542,133 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2083 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2074 +#: src/mail.cpp:2090 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2088 +#: src/mail.cpp:2104 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2089 +#: src/mail.cpp:2105 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2097 +#: src/mail.cpp:2113 #, fuzzy msgid "The signature is invalid: \n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2102 +#: src/mail.cpp:2118 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2122 #, fuzzy msgid "The signature is expired.\n" msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used key" msgstr "" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 #, fuzzy msgid "The used certificate" msgstr "Validering" -#: src/mail.cpp:2118 +#: src/mail.cpp:2134 #, fuzzy msgid "is not available." msgstr "Sp?rrlistan ?r inte tillg?nglig\n" -#: src/mail.cpp:2122 +#: src/mail.cpp:2138 msgid "is revoked." msgstr "" -#: src/mail.cpp:2126 +#: src/mail.cpp:2142 msgid "is expired." msgstr "" -#: src/mail.cpp:2130 +#: src/mail.cpp:2146 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2134 src/mail.cpp:2138 +#: src/mail.cpp:2150 src/mail.cpp:2154 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2143 +#: src/mail.cpp:2159 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2149 +#: src/mail.cpp:2165 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2178 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2166 +#: src/mail.cpp:2182 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2187 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2191 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2185 +#: src/mail.cpp:2201 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2189 +#: src/mail.cpp:2205 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2197 +#: src/mail.cpp:2213 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2201 +#: src/mail.cpp:2217 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "Den h?r signaturen ?r giltig\n" -#: src/mail.cpp:2212 +#: src/mail.cpp:2228 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2216 +#: src/mail.cpp:2232 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2217 +#: src/mail.cpp:2233 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2221 +#: src/mail.cpp:2237 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2222 +#: src/mail.cpp:2238 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" @@ -683,11 +683,11 @@ msgstr "" "och inte RTF-meddelanden. Se till att endast textformatet\n" "har valts i inst?llningarna." -#: src/mailitem-events.cpp:292 +#: src/mailitem-events.cpp:295 msgid "Sorry, that's not possible, yet" msgstr "" -#: src/mailitem-events.cpp:294 +#: src/mailitem-events.cpp:297 #, c-format msgid "" "GpgOL has prevented the change to the \"%s\" property.\n" @@ -699,12 +699,12 @@ msgid "" "For example by right clicking but not selecting the message.\n" msgstr "" -#: src/mailitem-events.cpp:380 +#: src/mailitem-events.cpp:385 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "Dekryptera och validera meddelandet." -#: src/mailitem-events.cpp:382 +#: src/mailitem-events.cpp:387 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -719,28 +719,28 @@ msgstr "" msgid "Note: Using compatibility flags: %s" msgstr "" -#: src/mapihelp.cpp:1786 src/mapihelp.cpp:1794 src/mapihelp.cpp:1802 +#: src/mapihelp.cpp:1807 src/mapihelp.cpp:1815 src/mapihelp.cpp:1823 msgid "[no subject]" msgstr "" -#: src/mapihelp.cpp:2427 +#: src/mapihelp.cpp:2448 msgid "" "[The content of this message is not visible because it has been decrypted by " "another Outlook session. Use the \"decrypt/verify\" command to make it " "visible]" msgstr "" -#: src/mapihelp.cpp:3310 +#: src/mapihelp.cpp:3331 msgid "" "[The content of this message is not visible due to an processing error in " "GpgOL.]" msgstr "" -#: src/message.cpp:178 +#: src/message.cpp:179 msgid "[Crypto operation failed - can't show the body of the message]" msgstr "" -#: src/message.cpp:280 +#: src/message.cpp:281 #, c-format msgid "" "Signature status: %s\n" @@ -749,54 +749,54 @@ msgid "" "%s" msgstr "" -#: src/message.cpp:288 +#: src/message.cpp:289 msgid "GpgOL - Message Information" msgstr "" -#: src/message.cpp:520 +#: src/message.cpp:521 msgid "Signature verification of an encrypted message is not possible." msgstr "" -#: src/message.cpp:531 +#: src/message.cpp:532 msgid "Signature verification of this message class is not possible." msgstr "" -#: src/message.cpp:534 +#: src/message.cpp:535 msgid "" "Signature verification of this S/MIME message is not possible. Please check " "that S/MIME processing has been enabled." msgstr "" -#: src/message.cpp:538 +#: src/message.cpp:539 #, fuzzy msgid "This message has no signature." msgstr "Dekryptera meddelandet och validera signaturen" -#: src/message.cpp:706 +#: src/message.cpp:707 msgid "This message is not encrypted." msgstr "" -#: src/message.cpp:933 +#: src/message.cpp:934 #, fuzzy, c-format msgid "" "Decryption failed\n" "(%s)" msgstr "Kryptering misslyckades" -#: src/message.cpp:1094 +#: src/message.cpp:1105 msgid "No recipients to encrypt to are given" msgstr "" -#: src/message.cpp:1109 src/message.cpp:1136 +#: src/message.cpp:1120 src/message.cpp:1147 msgid "Encrypting or signing an empty message is not possible." msgstr "" -#: src/message.cpp:1117 +#: src/message.cpp:1128 #, fuzzy, c-format msgid "Encryption failed (%s)" msgstr "Kryptering misslyckades" -#: src/message.cpp:1145 +#: src/message.cpp:1156 #, fuzzy, c-format msgid "Signing failed (%s)" msgstr "Signering misslyckades" diff --git a/po/zh_CN.po b/po/zh_CN.po index a698198..1f7a8c0 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2017-12-08 10:21+0100\n" +"POT-Creation-Date: 2018-01-12 10:52+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -76,7 +76,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:300 +#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:301 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -167,12 +167,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1626 src/mail.cpp:1697 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1642 src/mail.cpp:1713 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1627 src/mail.cpp:1698 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1643 src/mail.cpp:1714 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -365,51 +365,51 @@ msgstr "" "???????\n" "???????????" -#: src/mail.cpp:344 +#: src/mail.cpp:352 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:349 +#: src/mail.cpp:357 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:354 +#: src/mail.cpp:362 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:394 +#: src/mail.cpp:402 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:397 +#: src/mail.cpp:405 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:753 src/mail.cpp:1941 +#: src/mail.cpp:763 src/mail.cpp:1957 #, fuzzy msgid "Encrypted message" msgstr "????" -#: src/mail.cpp:754 +#: src/mail.cpp:764 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1002 +#: src/mail.cpp:1012 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1006 +#: src/mail.cpp:1016 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -417,7 +417,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1021 +#: src/mail.cpp:1031 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -425,7 +425,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1036 +#: src/mail.cpp:1046 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -435,105 +435,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:1886 +#: src/mail.cpp:1902 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1890 +#: src/mail.cpp:1906 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1894 +#: src/mail.cpp:1910 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1898 +#: src/mail.cpp:1914 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1902 +#: src/mail.cpp:1918 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1906 +#: src/mail.cpp:1922 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1910 +#: src/mail.cpp:1926 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:1919 src/mail.cpp:1921 src/ribbon-callbacks.cpp:1604 +#: src/mail.cpp:1935 src/mail.cpp:1937 src/ribbon-callbacks.cpp:1604 msgid "Insecure" msgstr "" -#: src/mail.cpp:1933 +#: src/mail.cpp:1949 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:1937 +#: src/mail.cpp:1953 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:1944 src/ribbon-callbacks.cpp:1627 +#: src/mail.cpp:1960 src/ribbon-callbacks.cpp:1627 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:1955 src/mail.cpp:1966 +#: src/mail.cpp:1971 src/mail.cpp:1982 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1958 +#: src/mail.cpp:1974 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:1976 +#: src/mail.cpp:1992 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:1980 +#: src/mail.cpp:1996 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:1984 +#: src/mail.cpp:2000 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:2023 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2011 +#: src/mail.cpp:2027 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:2031 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2028 +#: src/mail.cpp:2044 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2049 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2057 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2051 +#: src/mail.cpp:2067 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -541,133 +541,133 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2083 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2074 +#: src/mail.cpp:2090 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2088 +#: src/mail.cpp:2104 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2089 +#: src/mail.cpp:2105 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2097 +#: src/mail.cpp:2113 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2102 +#: src/mail.cpp:2118 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2122 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used key" msgstr "" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2118 +#: src/mail.cpp:2134 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2122 +#: src/mail.cpp:2138 msgid "is revoked." msgstr "" -#: src/mail.cpp:2126 +#: src/mail.cpp:2142 msgid "is expired." msgstr "" -#: src/mail.cpp:2130 +#: src/mail.cpp:2146 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2134 src/mail.cpp:2138 +#: src/mail.cpp:2150 src/mail.cpp:2154 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2143 +#: src/mail.cpp:2159 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2149 +#: src/mail.cpp:2165 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2178 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2166 +#: src/mail.cpp:2182 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2187 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2191 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2185 +#: src/mail.cpp:2201 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2189 +#: src/mail.cpp:2205 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2197 +#: src/mail.cpp:2213 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2201 +#: src/mail.cpp:2217 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2212 +#: src/mail.cpp:2228 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2216 +#: src/mail.cpp:2232 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2217 +#: src/mail.cpp:2233 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2221 +#: src/mail.cpp:2237 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2222 +#: src/mail.cpp:2238 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" @@ -681,11 +681,11 @@ msgstr "" "?????????????????\n" "????" -#: src/mailitem-events.cpp:292 +#: src/mailitem-events.cpp:295 msgid "Sorry, that's not possible, yet" msgstr "" -#: src/mailitem-events.cpp:294 +#: src/mailitem-events.cpp:297 #, c-format msgid "" "GpgOL has prevented the change to the \"%s\" property.\n" @@ -697,12 +697,12 @@ msgid "" "For example by right clicking but not selecting the message.\n" msgstr "" -#: src/mailitem-events.cpp:380 +#: src/mailitem-events.cpp:385 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mailitem-events.cpp:382 +#: src/mailitem-events.cpp:387 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -717,11 +717,11 @@ msgstr "" msgid "Note: Using compatibility flags: %s" msgstr "???????????%s" -#: src/mapihelp.cpp:1786 src/mapihelp.cpp:1794 src/mapihelp.cpp:1802 +#: src/mapihelp.cpp:1807 src/mapihelp.cpp:1815 src/mapihelp.cpp:1823 msgid "[no subject]" msgstr "[???]" -#: src/mapihelp.cpp:2427 +#: src/mapihelp.cpp:2448 msgid "" "[The content of this message is not visible because it has been decrypted by " "another Outlook session. Use the \"decrypt/verify\" command to make it " @@ -730,17 +730,17 @@ msgstr "" "[???????????????? Outlook ?????????/????????" "?]" -#: src/mapihelp.cpp:3310 +#: src/mapihelp.cpp:3331 msgid "" "[The content of this message is not visible due to an processing error in " "GpgOL.]" msgstr "[???????? GpgOL ????]" -#: src/message.cpp:178 +#: src/message.cpp:179 msgid "[Crypto operation failed - can't show the body of the message]" msgstr "[?????????????????]" -#: src/message.cpp:280 +#: src/message.cpp:281 #, c-format msgid "" "Signature status: %s\n" @@ -753,33 +753,33 @@ msgstr "" "MIME ???\n" "%s" -#: src/message.cpp:288 +#: src/message.cpp:289 msgid "GpgOL - Message Information" msgstr "GpgOL - ????" -#: src/message.cpp:520 +#: src/message.cpp:521 msgid "Signature verification of an encrypted message is not possible." msgstr "??????????????" -#: src/message.cpp:531 +#: src/message.cpp:532 msgid "Signature verification of this message class is not possible." msgstr "???????????" -#: src/message.cpp:534 +#: src/message.cpp:535 msgid "" "Signature verification of this S/MIME message is not possible. Please check " "that S/MIME processing has been enabled." msgstr "????? S/MIME ?????? S/MIME ??????" -#: src/message.cpp:538 +#: src/message.cpp:539 msgid "This message has no signature." msgstr "????????" -#: src/message.cpp:706 +#: src/message.cpp:707 msgid "This message is not encrypted." msgstr "????????" -#: src/message.cpp:933 +#: src/message.cpp:934 #, c-format msgid "" "Decryption failed\n" @@ -788,20 +788,20 @@ msgstr "" "????\n" "?%s?" -#: src/message.cpp:1094 +#: src/message.cpp:1105 msgid "No recipients to encrypt to are given" msgstr "????????????" -#: src/message.cpp:1109 src/message.cpp:1136 +#: src/message.cpp:1120 src/message.cpp:1147 msgid "Encrypting or signing an empty message is not possible." msgstr "???????????" -#: src/message.cpp:1117 +#: src/message.cpp:1128 #, c-format msgid "Encryption failed (%s)" msgstr "???? (%s)" -#: src/message.cpp:1145 +#: src/message.cpp:1156 #, c-format msgid "Signing failed (%s)" msgstr "???? (%s)" diff --git a/po/zh_TW.po b/po/zh_TW.po index 6f6f59e..fbd3ad6 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GpgOL\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" -"POT-Creation-Date: 2017-12-08 10:21+0100\n" +"POT-Creation-Date: 2018-01-12 10:52+0100\n" "PO-Revision-Date: 2015-08-15 21:58+0800\n" "Last-Translator: Mingye Wang (Arthur2e5) \n" "Language-Team: \n" @@ -76,7 +76,7 @@ msgstr "" #: src/gpgoladdin.cpp:864 src/gpgoladdin.cpp:907 src/gpgoladdin.cpp:980 #: src/gpgoladdin.cpp:982 src/gpgoladdin.cpp:1018 src/gpgoladdin.cpp:1172 #: src/gpgoladdin.cpp:1255 src/gpgoladdin.cpp:1261 src/gpgoladdin.cpp:1334 -#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:300 +#: src/gpgoladdin.cpp:1338 src/main.c:467 src/message.cpp:301 #: src/ribbon-callbacks.cpp:134 src/ribbon-callbacks.cpp:248 #: src/ribbon-callbacks.cpp:263 src/ribbon-callbacks.cpp:275 #: src/ribbon-callbacks.cpp:312 src/ribbon-callbacks.cpp:324 @@ -167,12 +167,12 @@ msgstr "" msgid "Do you want to revert this folder?" msgstr "????????????" -#: src/gpgoladdin.cpp:446 src/mail.cpp:1626 src/mail.cpp:1697 +#: src/gpgoladdin.cpp:446 src/mail.cpp:1642 src/mail.cpp:1713 #, fuzzy msgid "GpgOL: Encrypted Message" msgstr "????" -#: src/gpgoladdin.cpp:447 src/mail.cpp:1627 src/mail.cpp:1698 +#: src/gpgoladdin.cpp:447 src/mail.cpp:1643 src/mail.cpp:1714 msgid "GpgOL: Trusted Sender Address" msgstr "" @@ -365,51 +365,51 @@ msgstr "" "???????\n" "???????????" -#: src/mail.cpp:344 +#: src/mail.cpp:352 msgid "" "Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:349 +#: src/mail.cpp:357 msgid "" "Not all attachments were signed.\n" "The unsigned attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:354 +#: src/mail.cpp:362 msgid "" "Not all attachments were encrypted.\n" "The unencrypted attachments are:\n" "\n" msgstr "" -#: src/mail.cpp:394 +#: src/mail.cpp:402 msgid "" "Note: The attachments may be encrypted or signed on a file level but the " "GpgOL status does not apply to them." msgstr "" -#: src/mail.cpp:397 +#: src/mail.cpp:405 msgid "GpgOL Warning" msgstr "" -#: src/mail.cpp:753 src/mail.cpp:1941 +#: src/mail.cpp:763 src/mail.cpp:1957 #, fuzzy msgid "Encrypted message" msgstr "????" -#: src/mail.cpp:754 +#: src/mail.cpp:764 msgid "Please wait while the message is being decrypted / verified..." msgstr "" -#: src/mail.cpp:1002 +#: src/mail.cpp:1012 msgid "GpgOL: Oops, G Suite Sync account detected" msgstr "" -#: src/mail.cpp:1006 +#: src/mail.cpp:1016 msgid "" "G Suite Sync breaks outgoing crypto mails with attachments.\n" "Using crypto and attachments with G Suite Sync is not supported.\n" @@ -417,7 +417,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1021 +#: src/mail.cpp:1031 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -425,7 +425,7 @@ msgid "" "See: https://dev.gnupg.org/T3545 for details." msgstr "" -#: src/mail.cpp:1036 +#: src/mail.cpp:1046 msgid "" "G Suite Sync breaks outgoing signed mails.\n" "Ensuring mail integrity (signing) with G Suite Sync is not supported.\n" @@ -435,105 +435,105 @@ msgid "" "Do you want to only encrypt the message?" msgstr "" -#: src/mail.cpp:1886 +#: src/mail.cpp:1902 msgid "Security Level 4" msgstr "" -#: src/mail.cpp:1890 +#: src/mail.cpp:1906 msgid "Trust Level 4" msgstr "" -#: src/mail.cpp:1894 +#: src/mail.cpp:1910 msgid "Security Level 3" msgstr "" -#: src/mail.cpp:1898 +#: src/mail.cpp:1914 msgid "Trust Level 3" msgstr "" -#: src/mail.cpp:1902 +#: src/mail.cpp:1918 msgid "Security Level 2" msgstr "" -#: src/mail.cpp:1906 +#: src/mail.cpp:1922 msgid "Trust Level 2" msgstr "" -#: src/mail.cpp:1910 +#: src/mail.cpp:1926 #, fuzzy msgid "Encrypted" msgstr "??" -#: src/mail.cpp:1919 src/mail.cpp:1921 src/ribbon-callbacks.cpp:1604 +#: src/mail.cpp:1935 src/mail.cpp:1937 src/ribbon-callbacks.cpp:1604 msgid "Insecure" msgstr "" -#: src/mail.cpp:1933 +#: src/mail.cpp:1949 #, fuzzy msgid "Signed and encrypted message" msgstr "????" -#: src/mail.cpp:1937 +#: src/mail.cpp:1953 #, fuzzy msgid "Signed message" msgstr "????" -#: src/mail.cpp:1944 src/ribbon-callbacks.cpp:1627 +#: src/mail.cpp:1960 src/ribbon-callbacks.cpp:1627 #, fuzzy msgid "Insecure message" msgstr "????" -#: src/mail.cpp:1955 src/mail.cpp:1966 +#: src/mail.cpp:1971 src/mail.cpp:1982 msgid "You cannot be sure who sent, modified and read the message in transit." msgstr "" -#: src/mail.cpp:1958 +#: src/mail.cpp:1974 msgid "The message was signed but the verification failed with:" msgstr "" -#: src/mail.cpp:1976 +#: src/mail.cpp:1992 #, fuzzy msgid "The encryption was VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:1980 +#: src/mail.cpp:1996 #, fuzzy msgid "The encryption was not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:1984 +#: src/mail.cpp:2000 msgid "You cannot be sure who sent the message because it is not signed." msgstr "" -#: src/mail.cpp:2007 +#: src/mail.cpp:2023 #, fuzzy msgid "You signed this message." msgstr "????" -#: src/mail.cpp:2011 +#: src/mail.cpp:2027 msgid "The senders identity was certified by yourself." msgstr "" -#: src/mail.cpp:2015 +#: src/mail.cpp:2031 msgid "The sender is allowed to certify identities for you." msgstr "" -#: src/mail.cpp:2028 +#: src/mail.cpp:2044 msgid "The senders identity was certified by several trusted people." msgstr "" -#: src/mail.cpp:2033 +#: src/mail.cpp:2049 #, c-format msgid "" "The senders identity is certified by the trusted issuer:\n" "'%s'\n" msgstr "" -#: src/mail.cpp:2041 +#: src/mail.cpp:2057 msgid "Some trusted people have certified the senders identity." msgstr "" -#: src/mail.cpp:2051 +#: src/mail.cpp:2067 #, c-format msgid "" "The senders address is trusted, because you have established a communication " @@ -541,133 +541,133 @@ msgid "" "You encrypted %i and verified %i messages since." msgstr "" -#: src/mail.cpp:2067 +#: src/mail.cpp:2083 msgid "The senders signature was verified for the first time." msgstr "" -#: src/mail.cpp:2074 +#: src/mail.cpp:2090 #, c-format msgid "" "The senders address is not trustworthy yet because you only verified %i " "messages and encrypted %i messages to it since %s." msgstr "" -#: src/mail.cpp:2088 +#: src/mail.cpp:2104 msgid "But the sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2089 +#: src/mail.cpp:2105 msgid "The sender address is not trustworthy because:" msgstr "" -#: src/mail.cpp:2097 +#: src/mail.cpp:2113 #, fuzzy msgid "The signature is invalid: \n" msgstr "????\n" -#: src/mail.cpp:2102 +#: src/mail.cpp:2118 msgid "There was an error verifying the signature.\n" msgstr "" -#: src/mail.cpp:2106 +#: src/mail.cpp:2122 #, fuzzy msgid "The signature is expired.\n" msgstr "????\n" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 msgid "The used key" msgstr "" -#: src/mail.cpp:2110 +#: src/mail.cpp:2126 #, fuzzy msgid "The used certificate" msgstr "????" -#: src/mail.cpp:2118 +#: src/mail.cpp:2134 #, fuzzy msgid "is not available." msgstr "???????CRL????\n" -#: src/mail.cpp:2122 +#: src/mail.cpp:2138 msgid "is revoked." msgstr "" -#: src/mail.cpp:2126 +#: src/mail.cpp:2142 msgid "is expired." msgstr "" -#: src/mail.cpp:2130 +#: src/mail.cpp:2146 msgid "is not meant for signing." msgstr "" -#: src/mail.cpp:2134 src/mail.cpp:2138 +#: src/mail.cpp:2150 src/mail.cpp:2154 msgid "could not be checked for revocation." msgstr "" -#: src/mail.cpp:2143 +#: src/mail.cpp:2159 msgid "is not the same as the key that was used for this address in the past." msgstr "" -#: src/mail.cpp:2149 +#: src/mail.cpp:2165 #, c-format msgid "does not claim the address: \"%s\"." msgstr "" -#: src/mail.cpp:2162 +#: src/mail.cpp:2178 msgid "is not certified by any trustworthy key." msgstr "" -#: src/mail.cpp:2166 +#: src/mail.cpp:2182 msgid "" "is not certified by a trustworthy Certificate Authority or the Certificate " "Authority is unknown." msgstr "" -#: src/mail.cpp:2171 +#: src/mail.cpp:2187 msgid "The sender marked this address as revoked." msgstr "" -#: src/mail.cpp:2175 +#: src/mail.cpp:2191 msgid "is marked as not trustworthy." msgstr "" -#: src/mail.cpp:2185 +#: src/mail.cpp:2201 #, fuzzy msgid "The signature is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2189 +#: src/mail.cpp:2205 #, fuzzy msgid "The signature is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2197 +#: src/mail.cpp:2213 #, fuzzy msgid "The encryption is VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2201 +#: src/mail.cpp:2217 #, fuzzy msgid "The encryption is not VS-NfD-compliant." msgstr "????\n" -#: src/mail.cpp:2212 +#: src/mail.cpp:2228 msgid "Click here to change the key used for this address." msgstr "" -#: src/mail.cpp:2216 +#: src/mail.cpp:2232 msgid "Click here for details about the key." msgstr "" -#: src/mail.cpp:2217 +#: src/mail.cpp:2233 msgid "Click here for details about the certificate." msgstr "" -#: src/mail.cpp:2221 +#: src/mail.cpp:2237 msgid "Click here to search the key on the configured keyserver." msgstr "" -#: src/mail.cpp:2222 +#: src/mail.cpp:2238 msgid "Click here to search the certificate on the configured X509 keyserver." msgstr "" @@ -681,11 +681,11 @@ msgstr "" "?????????????????\n" "????" -#: src/mailitem-events.cpp:292 +#: src/mailitem-events.cpp:295 msgid "Sorry, that's not possible, yet" msgstr "" -#: src/mailitem-events.cpp:294 +#: src/mailitem-events.cpp:297 #, c-format msgid "" "GpgOL has prevented the change to the \"%s\" property.\n" @@ -697,12 +697,12 @@ msgid "" "For example by right clicking but not selecting the message.\n" msgstr "" -#: src/mailitem-events.cpp:380 +#: src/mailitem-events.cpp:385 #, fuzzy msgid "GpgOL: Encryption not possible!" msgstr "????" -#: src/mailitem-events.cpp:382 +#: src/mailitem-events.cpp:387 msgid "" "Outlook returned an error when trying to send the encrypted mail.\n" "\n" @@ -717,11 +717,11 @@ msgstr "" msgid "Note: Using compatibility flags: %s" msgstr "???????????%s" -#: src/mapihelp.cpp:1786 src/mapihelp.cpp:1794 src/mapihelp.cpp:1802 +#: src/mapihelp.cpp:1807 src/mapihelp.cpp:1815 src/mapihelp.cpp:1823 msgid "[no subject]" msgstr "[???]" -#: src/mapihelp.cpp:2427 +#: src/mapihelp.cpp:2448 msgid "" "[The content of this message is not visible because it has been decrypted by " "another Outlook session. Use the \"decrypt/verify\" command to make it " @@ -730,17 +730,17 @@ msgstr "" "[???????????????? Outlook ?????????/????????" "?]" -#: src/mapihelp.cpp:3310 +#: src/mapihelp.cpp:3331 msgid "" "[The content of this message is not visible due to an processing error in " "GpgOL.]" msgstr "[???????? GpgOL ????]" -#: src/message.cpp:178 +#: src/message.cpp:179 msgid "[Crypto operation failed - can't show the body of the message]" msgstr "[?????????????????]" -#: src/message.cpp:280 +#: src/message.cpp:281 #, c-format msgid "" "Signature status: %s\n" @@ -753,33 +753,33 @@ msgstr "" "MIME ???\n" "%s" -#: src/message.cpp:288 +#: src/message.cpp:289 msgid "GpgOL - Message Information" msgstr "GpgOL - ????" -#: src/message.cpp:520 +#: src/message.cpp:521 msgid "Signature verification of an encrypted message is not possible." msgstr "??????????????" -#: src/message.cpp:531 +#: src/message.cpp:532 msgid "Signature verification of this message class is not possible." msgstr "???????????" -#: src/message.cpp:534 +#: src/message.cpp:535 msgid "" "Signature verification of this S/MIME message is not possible. Please check " "that S/MIME processing has been enabled." msgstr "????? S/MIME ?????? S/MIME ??????" -#: src/message.cpp:538 +#: src/message.cpp:539 msgid "This message has no signature." msgstr "????????" -#: src/message.cpp:706 +#: src/message.cpp:707 msgid "This message is not encrypted." msgstr "????????" -#: src/message.cpp:933 +#: src/message.cpp:934 #, c-format msgid "" "Decryption failed\n" @@ -788,20 +788,20 @@ msgstr "" "????\n" "?%s?" -#: src/message.cpp:1094 +#: src/message.cpp:1105 msgid "No recipients to encrypt to are given" msgstr "????????????" -#: src/message.cpp:1109 src/message.cpp:1136 +#: src/message.cpp:1120 src/message.cpp:1147 msgid "Encrypting or signing an empty message is not possible." msgstr "???????????" -#: src/message.cpp:1117 +#: src/message.cpp:1128 #, c-format msgid "Encryption failed (%s)" msgstr "???? (%s)" -#: src/message.cpp:1145 +#: src/message.cpp:1156 #, c-format msgid "Signing failed (%s)" msgstr "???? (%s)" ----------------------------------------------------------------------- Summary of changes: NEWS | 5 ++ configure.ac | 2 +- po/de.po | 174 +++++++++++++++++++++++++++++------------------------------ po/fr.po | 174 +++++++++++++++++++++++++++++------------------------------ po/pt.po | 174 +++++++++++++++++++++++++++++------------------------------ po/sv.po | 174 +++++++++++++++++++++++++++++------------------------------ po/zh_CN.po | 174 +++++++++++++++++++++++++++++------------------------------ po/zh_TW.po | 174 +++++++++++++++++++++++++++++------------------------------ 8 files changed, 528 insertions(+), 523 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 12 13:46:24 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 12 Jan 2018 13:46:24 +0100 Subject: [git] gnupg-doc - branch, master, updated. 76802d1db0d7ef9bf9376907d86e75b5edd78ba2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 76802d1db0d7ef9bf9376907d86e75b5edd78ba2 (commit) from 3fe91c68480c1c11a66b7a9931450f5f9c9e3701 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 76802d1db0d7ef9bf9376907d86e75b5edd78ba2 Author: Andre Heinecke Date: Fri Jan 12 13:45:51 2018 +0100 SWDB: Update for gpg4win-3.0.3 -- diff --git a/web/swdb.mac b/web/swdb.mac index 2f87b99..1ae47f2 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -66,17 +66,17 @@ # # Gpg4win # -#+macro: gpg4win_ver 3.0.2 -#+macro: gpg4win_date 2017-12-08 +#+macro: gpg4win_ver 3.0.3 +#+macro: gpg4win_date 2018-01-12 #+macro: gpg4win_src_size 5226k -#+macro: gpg4win_src_sha1 53f1690b4377e2d7c9931977630a05caa8fafe14 -#+macro: gpg4win_src_sha2 eda921939189648ad01156a153545941916457c0b94bff19026df3c296e326ab -#+macro: gpg4win_exe_size 26343k -#+macro: gpg4win_exe_sha1 a2dabaf0a65f3ef30c60e7522f3459c81120098e -#+macro: gpg4win_exe_sha2 c4c4e5724e9581fdcf00241b33d18eee363a1fb6cc6a737d8cb2877e3b4f9298 -#+macro: gpg4win_isrc_size 220262k -#+macro: gpg4win_isrc_sha1 51494bb278720bbe83d4fbc47543f0a1e374826b -#+macro: gpg4win_isrc_sha2 7a162a875676857d2b9927b1bbd611e24d4d670b43a25e1b6a8c771ac3253408 +#+macro: gpg4win_src_sha1 4be455a6e8176054ce940ae68890e8aa82a99137 +#+macro: gpg4win_src_sha2 fda270694eca7f4a6767e3a239d15d1166313c397cf83d6d06ad962a7a13717b +#+macro: gpg4win_exe_size 26357k +#+macro: gpg4win_exe_sha1 e901af858a964192cec891cdbae76ca6789d741c +#+macro: gpg4win_exe_sha2 477f56212ee60cc74e0c5e5cc526cec52a069abff485c89c2d57d1b4b6a54971 +#+macro: gpg4win_isrc_size 220342k +#+macro: gpg4win_isrc_sha1 cb259311fe133017847981f31cb9b1fba6e2e456 +#+macro: gpg4win_isrc_sha2 41cb2a6d17ab0b0a0bd45a06e4dcc421191297e928a23afdf7ff8a349dedc59e # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 12 18:36:54 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Fri, 12 Jan 2018 18:36:54 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-35-gc3d60ac Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via c3d60acc3ab5c6d60c2258882175bf31351cc998 (commit) via a518b6680ea80a4325731028545a701c1d71fc02 (commit) via 135250e3060e79be698d4f36a819aa8a880789f8 (commit) from a00c5b2988cea256c7823a76ce601febf02c790f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c3d60acc3ab5c6d60c2258882175bf31351cc998 Author: Jussi Kivilinna Date: Sat Jan 6 23:21:44 2018 +0200 rijndael-ssse3: call assembly functions directly * cipher/rijndael-ssse3-amd64-asm.S (_gcry_aes_ssse3_enc_preload) (_gcry_aes_ssse3_dec_preload, _gcry_aes_ssse3_encrypt_core) (_gcry_aes_ssse3_decrypt_core, _gcry_aes_schedule_core): Add ENTER_SYSV_FUNC_PARAMS_* at function entry and EXIT_SYSV_FUNC at exit. (_gcry_aes_ssse3_encrypt_core, _gcry_aes_ssse3_decrypt_core): Change to input parameters to RDI and RSI registers. * cipher/rijndael-ssse3-amd64.c (_gcry_aes_ssse3_encrypt_core) (_gcry_aes_ssse3_decrypt_core, _gcry_aes_schedule_core): Add parameters for function prototypes. (PUSH_STACK_PTR, POP_STACK_PTR): Remove. (vpaes_ssse3_prepare_enc, vpaes_ssse3_prepare_dec) (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption) (do_vpaes_ssse3_enc, do_vpaes_ssse3_dec): Remove inline assembly to call functions, and call directly instead. -- Instead of using inline assembly to call assembly functions in AES SSSE3 implementation, change assembly functions so that they can be called directly instead. Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael-ssse3-amd64-asm.S b/cipher/rijndael-ssse3-amd64-asm.S index 3ae55e8..ffce5df 100644 --- a/cipher/rijndael-ssse3-amd64-asm.S +++ b/cipher/rijndael-ssse3-amd64-asm.S @@ -40,11 +40,7 @@ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS -# define ELF(...) -#else -# define ELF(...) __VA_ARGS__ -#endif +#include "asm-common-amd64.h" .text @@ -54,6 +50,7 @@ ELF(.type _gcry_aes_ssse3_enc_preload, at function) .globl _gcry_aes_ssse3_enc_preload _gcry_aes_ssse3_enc_preload: + ENTER_SYSV_FUNC_PARAMS_0_4 lea .Laes_consts(%rip), %rax movdqa (%rax), %xmm9 # 0F movdqa .Lk_inv (%rax), %xmm10 # inv @@ -62,6 +59,7 @@ _gcry_aes_ssse3_enc_preload: movdqa .Lk_sb1+16(%rax), %xmm12 # sb1t movdqa .Lk_sb2 (%rax), %xmm15 # sb2u movdqa .Lk_sb2+16(%rax), %xmm14 # sb2t + EXIT_SYSV_FUNC ret ELF(.size _gcry_aes_ssse3_enc_preload,.-_gcry_aes_ssse3_enc_preload) @@ -71,6 +69,7 @@ ELF(.size _gcry_aes_ssse3_enc_preload,.-_gcry_aes_ssse3_enc_preload) ELF(.type _gcry_aes_ssse3_dec_preload, at function) .globl _gcry_aes_ssse3_dec_preload _gcry_aes_ssse3_dec_preload: + ENTER_SYSV_FUNC_PARAMS_0_4 lea .Laes_consts(%rip), %rax movdqa (%rax), %xmm9 # 0F movdqa .Lk_inv (%rax), %xmm10 # inv @@ -80,6 +79,7 @@ _gcry_aes_ssse3_dec_preload: movdqa .Lk_dsbd (%rax), %xmm15 # sbdu movdqa .Lk_dsbb (%rax), %xmm14 # sbbu movdqa .Lk_dsbe (%rax), %xmm8 # sbeu + EXIT_SYSV_FUNC ret ELF(.size _gcry_aes_ssse3_dec_preload,.-_gcry_aes_ssse3_dec_preload) @@ -98,11 +98,11 @@ ELF(.size _gcry_aes_ssse3_dec_preload,.-_gcry_aes_ssse3_dec_preload) ## Inputs: ## %xmm0 = input ## %xmm9-%xmm15 as in .Laes_preheat -## (%rdx) = scheduled keys -## %rax = nrounds - 1 +## (%rdi) = scheduled keys +## %rsi = nrounds ## ## Output in %xmm0 -## Clobbers %xmm1-%xmm4, %r9, %r11, %rax, %rcx +## Clobbers %xmm1-%xmm4, %r9, %r11, %rax, %rcx, %rdx ## Preserves %xmm6 - %xmm7 so you get some local vectors ## ## @@ -111,6 +111,9 @@ ELF(.type _gcry_aes_ssse3_encrypt_core, at function) .globl _gcry_aes_ssse3_encrypt_core _gcry_aes_ssse3_encrypt_core: _aes_encrypt_core: + ENTER_SYSV_FUNC_PARAMS_0_4 + mov %rdi, %rdx + leaq -1(%rsi), %rax lea .Laes_consts(%rip), %rcx leaq .Lk_mc_backward(%rcx), %rdi mov $16, %rsi @@ -185,6 +188,7 @@ _aes_encrypt_core: pshufb %xmm3, %xmm0 # 0 = sb1t pxor %xmm4, %xmm0 # 0 = A pshufb .Lk_sr(%rsi,%rcx), %xmm0 + EXIT_SYSV_FUNC ret ELF(.size _aes_encrypt_core,.-_aes_encrypt_core) @@ -198,8 +202,11 @@ ELF(.size _aes_encrypt_core,.-_aes_encrypt_core) ELF(.type _gcry_aes_ssse3_decrypt_core, at function) _gcry_aes_ssse3_decrypt_core: _aes_decrypt_core: + ENTER_SYSV_FUNC_PARAMS_0_4 + mov %rdi, %rdx lea .Laes_consts(%rip), %rcx - movl %eax, %esi + subl $1, %esi + movl %esi, %eax shll $4, %esi xorl $48, %esi andl $48, %esi @@ -288,6 +295,7 @@ _aes_decrypt_core: pshufb %xmm3, %xmm0 # 0 = sb1t pxor %xmm4, %xmm0 # 0 = A pshufb .Lk_sr(%rsi,%rcx), %xmm0 + EXIT_SYSV_FUNC ret ELF(.size _aes_decrypt_core,.-_aes_decrypt_core) @@ -306,6 +314,8 @@ _aes_schedule_core: # rsi = size in bits # rdx = buffer # rcx = direction. 0=encrypt, 1=decrypt + # r8 = rotoffs + ENTER_SYSV_FUNC_PARAMS_5 # load the tables lea .Laes_consts(%rip), %r10 @@ -659,8 +669,9 @@ _aes_schedule_core: pxor %xmm6, %xmm6 pxor %xmm7, %xmm7 pxor %xmm8, %xmm8 + EXIT_SYSV_FUNC ret -ELF(.size _aes_schedule_core,.-_aes_schedule_core) +ELF(.size _gcry_aes_ssse3_schedule_core,.-_gcry_aes_ssse3_schedule_core) ######################################################## ## ## diff --git a/cipher/rijndael-ssse3-amd64.c b/cipher/rijndael-ssse3-amd64.c index da5339e..98660ec 100644 --- a/cipher/rijndael-ssse3-amd64.c +++ b/cipher/rijndael-ssse3-amd64.c @@ -58,13 +58,14 @@ /* Assembly functions in rijndael-ssse3-amd64-asm.S. Note that these - have custom calling convention and need to be called from assembly - blocks, not directly. */ + have custom calling convention (additional XMM parameters). */ extern void _gcry_aes_ssse3_enc_preload(void); extern void _gcry_aes_ssse3_dec_preload(void); -extern void _gcry_aes_ssse3_schedule_core(void); -extern void _gcry_aes_ssse3_encrypt_core(void); -extern void _gcry_aes_ssse3_decrypt_core(void); +extern void _gcry_aes_ssse3_schedule_core(const void *key, u64 keybits, + void *buffer, u64 decrypt, + u64 rotoffs); +extern void _gcry_aes_ssse3_encrypt_core(const void *key, u64 nrounds); +extern void _gcry_aes_ssse3_decrypt_core(const void *key, u64 nrounds); @@ -110,8 +111,6 @@ extern void _gcry_aes_ssse3_decrypt_core(void); : \ : "r" (ssse3_state) \ : "memory" ) -# define PUSH_STACK_PTR -# define POP_STACK_PTR #else # define SSSE3_STATE_SIZE 1 # define vpaes_ssse3_prepare() (void)ssse3_state @@ -126,31 +125,15 @@ extern void _gcry_aes_ssse3_decrypt_core(void); "pxor %%xmm7, %%xmm7 \n\t" \ "pxor %%xmm8, %%xmm8 \n\t" \ ::: "memory" ) -/* Old GCC versions use red-zone of AMD64 SYSV ABI and stack pointer is - * not properly adjusted for assembly block. Therefore stack pointer - * needs to be manually corrected. */ -# define PUSH_STACK_PTR "subq $128, %%rsp;\n\t" -# define POP_STACK_PTR "addq $128, %%rsp;\n\t" #endif #define vpaes_ssse3_prepare_enc() \ vpaes_ssse3_prepare(); \ - asm volatile (PUSH_STACK_PTR \ - "callq *%q[core] \n\t" \ - POP_STACK_PTR \ - : \ - : [core] "r" (_gcry_aes_ssse3_enc_preload) \ - : "rax", "cc", "memory" ) + _gcry_aes_ssse3_enc_preload(); #define vpaes_ssse3_prepare_dec() \ vpaes_ssse3_prepare(); \ - asm volatile (PUSH_STACK_PTR \ - "callq *%q[core] \n\t" \ - POP_STACK_PTR \ - : \ - : [core] "r" (_gcry_aes_ssse3_dec_preload) \ - : "rax", "cc", "memory" ) - + _gcry_aes_ssse3_dec_preload(); void @@ -161,23 +144,7 @@ _gcry_aes_ssse3_do_setkey (RIJNDAEL_context *ctx, const byte *key) vpaes_ssse3_prepare(); - asm volatile ("leaq %q[key], %%rdi" "\n\t" - "movl %[bits], %%esi" "\n\t" - "leaq %[buf], %%rdx" "\n\t" - "movl %[dir], %%ecx" "\n\t" - "movl %[rotoffs], %%r8d" "\n\t" - PUSH_STACK_PTR - "callq *%q[core]" "\n\t" - POP_STACK_PTR - : - : [core] "r" (&_gcry_aes_ssse3_schedule_core), - [key] "m" (*key), - [bits] "g" (keybits), - [buf] "m" (ctx->keyschenc32[0][0]), - [dir] "g" (0), - [rotoffs] "g" (48) - : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi", - "cc", "memory"); + _gcry_aes_ssse3_schedule_core(key, keybits, &ctx->keyschenc32[0][0], 0, 48); /* Save key for setting up decryption. */ if (keybits > 192) @@ -216,23 +183,9 @@ _gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) vpaes_ssse3_prepare(); - asm volatile ("leaq %q[key], %%rdi" "\n\t" - "movl %[bits], %%esi" "\n\t" - "leaq %[buf], %%rdx" "\n\t" - "movl %[dir], %%ecx" "\n\t" - "movl %[rotoffs], %%r8d" "\n\t" - PUSH_STACK_PTR - "callq *%q[core]" "\n\t" - POP_STACK_PTR - : - : [core] "r" (_gcry_aes_ssse3_schedule_core), - [key] "m" (ctx->keyschdec32[0][0]), - [bits] "g" (keybits), - [buf] "m" (ctx->keyschdec32[ctx->rounds][0]), - [dir] "g" (1), - [rotoffs] "g" ((keybits == 192) ? 0 : 32) - : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi", - "cc", "memory"); + _gcry_aes_ssse3_schedule_core(&ctx->keyschdec32[0][0], keybits, + &ctx->keyschdec32[ctx->rounds][0], 1, + (keybits == 192) ? 0 : 32); vpaes_ssse3_cleanup(); } @@ -243,15 +196,7 @@ _gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) static inline void do_vpaes_ssse3_enc (const RIJNDAEL_context *ctx, unsigned int nrounds) { - unsigned int middle_rounds = nrounds - 1; - const void *keysched = ctx->keyschenc32; - - asm volatile (PUSH_STACK_PTR - "callq *%q[core]" "\n\t" - POP_STACK_PTR - : "+a" (middle_rounds), "+d" (keysched) - : [core] "r" (_gcry_aes_ssse3_encrypt_core) - : "rcx", "rsi", "rdi", "cc", "memory"); + _gcry_aes_ssse3_encrypt_core(ctx->keyschenc32, nrounds); } @@ -260,15 +205,7 @@ do_vpaes_ssse3_enc (const RIJNDAEL_context *ctx, unsigned int nrounds) static inline void do_vpaes_ssse3_dec (const RIJNDAEL_context *ctx, unsigned int nrounds) { - unsigned int middle_rounds = nrounds - 1; - const void *keysched = ctx->keyschdec32; - - asm volatile (PUSH_STACK_PTR - "callq *%q[core]" "\n\t" - POP_STACK_PTR - : "+a" (middle_rounds), "+d" (keysched) - : [core] "r" (_gcry_aes_ssse3_decrypt_core) - : "rcx", "rsi", "cc", "memory"); + _gcry_aes_ssse3_decrypt_core(ctx->keyschdec32, nrounds); } commit a518b6680ea80a4325731028545a701c1d71fc02 Author: Jussi Kivilinna Date: Sat Jan 6 22:19:56 2018 +0200 Move AMD64 MS to SysV calling convention conversion to assembly side * cipher/Makefile.am: Add 'asm-common-amd64.h'. * cipher/asm-common-amd64.h: New. * cipher/blowfish-amd64.S: Add ENTER_SYSV_FUNC_* and EXIT_SYSV_FUNC for each global function from 'asm-common-amd64.h'. * cipher/cast5-amd64.S: Ditto. * cipher/des-amd64.S: Ditto. * cipher/rijndael-amd64.S: Ditto. * cipher/twofish-amd64.S: Ditto. * cipher/arcfour-amd64.S: Ditto. * cipher/blowfish.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): Remove. * cipher/cast5.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): Remove. * cipher/twofish.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn, call_sysv_fn5, call_sysv_fn6): Remove. * cipher/rijndael.c (do_encrypt, do_decrypt) [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Remove assembly block for calling SysV ABI function. * cipher/arcfour.c [USE_AMD64_ASM] (encrypt_stream): Ditto. -- Old approach was to convert MS ABI to SysV ABI calling convention for AMD64 assembly functions at caller side. This patch moves calling convention conversion to assembly/callee side. Signed-off-by: Jussi Kivilinna diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 3c4eae0..bba815b 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -61,6 +61,7 @@ dsa-common.c rsa-common.c \ sha1.h EXTRA_libcipher_la_SOURCES = \ +asm-common-amd64.h \ arcfour.c arcfour-amd64.S \ blowfish.c blowfish-amd64.S blowfish-arm.S \ cast5.c cast5-amd64.S cast5-arm.S \ diff --git a/cipher/arcfour-amd64.S b/cipher/arcfour-amd64.S index 2e52ea0..c08f345 100644 --- a/cipher/arcfour-amd64.S +++ b/cipher/arcfour-amd64.S @@ -18,17 +18,14 @@ #if defined(USE_ARCFOUR) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) -#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS -# define ELF(...) __VA_ARGS__ -#else -# define ELF(...) /*_*/ -#endif +#include "asm-common-amd64.h" .text .align 16 .globl _gcry_arcfour_amd64 ELF(.type _gcry_arcfour_amd64, at function) _gcry_arcfour_amd64: + ENTER_SYSV_FUNC_PARAMS_0_4 push %rbp push %rbx mov %rdi, %rbp # key = ARG(key) @@ -96,6 +93,7 @@ _gcry_arcfour_amd64: movb %dl, (4*256+4)(%rbp) # key->x = x pop %rbx pop %rbp + EXIT_SYSV_FUNC ret .L__gcry_arcfour_amd64_end: ELF(.size _gcry_arcfour_amd64,.L__gcry_arcfour_amd64_end-_gcry_arcfour_amd64) diff --git a/cipher/arcfour.c b/cipher/arcfour.c index 44e8ef4..085df9b 100644 --- a/cipher/arcfour.c +++ b/cipher/arcfour.c @@ -54,21 +54,7 @@ static void encrypt_stream (void *context, byte *outbuf, const byte *inbuf, size_t length) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - const void *fn = _gcry_arcfour_amd64; - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - asm volatile ("callq *%0\n\t" - : "+a" (fn), - "+D" (context), - "+S" (length), - "+d" (inbuf), - "+c" (outbuf) - : - : "cc", "memory", "r8", "r9", "r10", "r11"); -#else _gcry_arcfour_amd64 (context, length, inbuf, outbuf ); -#endif } #else /*!USE_AMD64_ASM*/ diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h new file mode 100644 index 0000000..7eb4264 --- /dev/null +++ b/cipher/asm-common-amd64.h @@ -0,0 +1,90 @@ +/* asm-common-amd64.h - Common macros for AMD64 assembly + * + * Copyright (C) 2018 Jussi Kivilinna + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef GCRY_ASM_COMMON_AMD64_H +#define GCRY_ASM_COMMON_AMD64_H + +#include + +#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS +# define ELF(...) __VA_ARGS__ +#else +# define ELF(...) /*_*/ +#endif + +#ifdef __PIC__ +# define rRIP (%rip) +#else +# define rRIP +#endif + +#ifdef __PIC__ +# define RIP %rip +#else +# define RIP +#endif + +#if defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS) || !defined(__PIC__) +# define GET_EXTERN_POINTER(name, reg) movabsq $name, reg +#else +# ifdef __code_model_large__ +# define GET_EXTERN_POINTER(name, reg) \ + pushq %r15; \ + pushq %r14; \ + 1: leaq 1b(%rip), reg; \ + movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \ + movabsq $name at GOT, %r15; \ + addq %r14, reg; \ + popq %r14; \ + movq (reg, %r15), reg; \ + popq %r15; +# else +# define GET_EXTERN_POINTER(name, reg) movq name at GOTPCREL(%rip), reg +# endif +#endif + +#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS +# define ENTER_SYSV_FUNC_PARAMS_0_4 \ + pushq %rdi; \ + pushq %rsi; \ + movq %rcx, %rdi; \ + movq %rdx, %rsi; \ + movq %r8, %rdx; \ + movq %r9, %rcx; \ + +# define ENTER_SYSV_FUNC_PARAMS_5 \ + ENTER_SYSV_FUNC_PARAMS_0_4; \ + movq 0x38(%rsp), %r8; + +# define ENTER_SYSV_FUNC_PARAMS_6 \ + ENTER_SYSV_FUNC_PARAMS_5; \ + movq 0x40(%rsp), %r9; + +# define EXIT_SYSV_FUNC \ + popq %rsi; \ + popq %rdi; +#else +# define ENTER_SYSV_FUNC_PARAMS_0_4 +# define ENTER_SYSV_FUNC_PARAMS_5 +# define ENTER_SYSV_FUNC_PARAMS_6 +# define EXIT_SYSV_FUNC +#endif + +#endif /* GCRY_ASM_COMMON_AMD64_H */ diff --git a/cipher/blowfish-amd64.S b/cipher/blowfish-amd64.S index 21b63fc..02d3b71 100644 --- a/cipher/blowfish-amd64.S +++ b/cipher/blowfish-amd64.S @@ -24,11 +24,7 @@ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) -#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS -# define ELF(...) __VA_ARGS__ -#else -# define ELF(...) /*_*/ -#endif +#include "asm-common-amd64.h" .text @@ -165,6 +161,8 @@ _gcry_blowfish_amd64_do_encrypt: * %rsi: u32 *ret_xl * %rdx: u32 *ret_xr */ + ENTER_SYSV_FUNC_PARAMS_0_4 + movl (%rdx), RX0d; shlq $32, RX0; movl (%rsi), RT3d; @@ -178,6 +176,7 @@ _gcry_blowfish_amd64_do_encrypt: shrq $32, RX0; movl RX0d, (RX2); + EXIT_SYSV_FUNC ret; ELF(.size _gcry_blowfish_amd64_do_encrypt,.-_gcry_blowfish_amd64_do_encrypt;) @@ -191,6 +190,7 @@ _gcry_blowfish_amd64_encrypt_block: * %rsi: dst * %rdx: src */ + ENTER_SYSV_FUNC_PARAMS_0_4 movq %rsi, %r10; @@ -202,6 +202,7 @@ _gcry_blowfish_amd64_encrypt_block: movq %r10, RIO; write_block(); + EXIT_SYSV_FUNC ret; ELF(.size _gcry_blowfish_amd64_encrypt_block,.-_gcry_blowfish_amd64_encrypt_block;) @@ -215,6 +216,8 @@ _gcry_blowfish_amd64_decrypt_block: * %rsi: dst * %rdx: src */ + ENTER_SYSV_FUNC_PARAMS_0_4 + movq %rbp, %r11; movq %rsi, %r10; @@ -238,6 +241,7 @@ _gcry_blowfish_amd64_decrypt_block: movq %r11, %rbp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_blowfish_amd64_decrypt_block,.-_gcry_blowfish_amd64_decrypt_block;) @@ -392,6 +396,8 @@ _gcry_blowfish_amd64_ctr_enc: * %rdx: src (4 blocks) * %rcx: iv (big endian, 64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 + pushq %rbp; pushq %rbx; pushq %r12; @@ -436,6 +442,7 @@ _gcry_blowfish_amd64_ctr_enc: popq %rbx; popq %rbp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_blowfish_amd64_ctr_enc,.-_gcry_blowfish_amd64_ctr_enc;) @@ -449,6 +456,8 @@ _gcry_blowfish_amd64_cbc_dec: * %rdx: src (4 blocks) * %rcx: iv (64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 + pushq %rbp; pushq %rbx; pushq %r12; @@ -484,6 +493,7 @@ _gcry_blowfish_amd64_cbc_dec: popq %rbx; popq %rbp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_blowfish_amd64_cbc_dec,.-_gcry_blowfish_amd64_cbc_dec;) @@ -497,6 +507,8 @@ _gcry_blowfish_amd64_cfb_dec: * %rdx: src (4 blocks) * %rcx: iv (64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 + pushq %rbp; pushq %rbx; pushq %r12; @@ -534,6 +546,8 @@ _gcry_blowfish_amd64_cfb_dec: popq %r12; popq %rbx; popq %rbp; + + EXIT_SYSV_FUNC ret; ELF(.size _gcry_blowfish_amd64_cfb_dec,.-_gcry_blowfish_amd64_cfb_dec;) diff --git a/cipher/blowfish.c b/cipher/blowfish.c index a3fc26c..724d64e 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -281,87 +281,43 @@ extern void _gcry_blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out, extern void _gcry_blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv); -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS -static inline void -call_sysv_fn (const void *fn, const void *arg1, const void *arg2, - const void *arg3, const void *arg4) -{ - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - asm volatile ("callq *%0\n\t" - : "+a" (fn), - "+D" (arg1), - "+S" (arg2), - "+d" (arg3), - "+c" (arg4) - : - : "cc", "memory", "r8", "r9", "r10", "r11"); -} -#endif - static void do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_blowfish_amd64_do_encrypt, bc, ret_xl, ret_xr, NULL); -#else _gcry_blowfish_amd64_do_encrypt (bc, ret_xl, ret_xr); -#endif } static void do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_blowfish_amd64_encrypt_block, context, outbuf, inbuf, - NULL); -#else _gcry_blowfish_amd64_encrypt_block (context, outbuf, inbuf); -#endif } static void do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_blowfish_amd64_decrypt_block, context, outbuf, inbuf, - NULL); -#else _gcry_blowfish_amd64_decrypt_block (context, outbuf, inbuf); -#endif } static inline void blowfish_amd64_ctr_enc(BLOWFISH_context *ctx, byte *out, const byte *in, byte *ctr) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_blowfish_amd64_ctr_enc, ctx, out, in, ctr); -#else _gcry_blowfish_amd64_ctr_enc(ctx, out, in, ctr); -#endif } static inline void blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_blowfish_amd64_cbc_dec, ctx, out, in, iv); -#else _gcry_blowfish_amd64_cbc_dec(ctx, out, in, iv); -#endif } static inline void blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_blowfish_amd64_cfb_dec, ctx, out, in, iv); -#else _gcry_blowfish_amd64_cfb_dec(ctx, out, in, iv); -#endif } static unsigned int diff --git a/cipher/cast5-amd64.S b/cipher/cast5-amd64.S index c04015a..1a1d43f 100644 --- a/cipher/cast5-amd64.S +++ b/cipher/cast5-amd64.S @@ -23,30 +23,7 @@ #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_CAST5) -#if defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS) || !defined(__PIC__) -# define GET_EXTERN_POINTER(name, reg) movabsq $name, reg -#else -# ifdef __code_model_large__ -# define GET_EXTERN_POINTER(name, reg) \ - pushq %r15; \ - pushq %r14; \ - 1: leaq 1b(%rip), reg; \ - movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \ - movabsq $name at GOT, %r15; \ - addq %r14, reg; \ - popq %r14; \ - movq (reg, %r15), reg; \ - popq %r15; -# else -# define GET_EXTERN_POINTER(name, reg) movq name at GOTPCREL(%rip), reg -# endif -#endif - -#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS -# define ELF(...) __VA_ARGS__ -#else -# define ELF(...) /*_*/ -#endif +#include "asm-common-amd64.h" .text @@ -206,6 +183,8 @@ _gcry_cast5_amd64_encrypt_block: * %rsi: dst * %rdx: src */ + ENTER_SYSV_FUNC_PARAMS_0_4 + pushq %rbp; pushq %rbx; @@ -233,6 +212,8 @@ _gcry_cast5_amd64_encrypt_block: popq %rbx; popq %rbp; + + EXIT_SYSV_FUNC ret; ELF(.size _gcry_cast5_amd64_encrypt_block,.-_gcry_cast5_amd64_encrypt_block;) @@ -246,6 +227,8 @@ _gcry_cast5_amd64_decrypt_block: * %rsi: dst * %rdx: src */ + ENTER_SYSV_FUNC_PARAMS_0_4 + pushq %rbp; pushq %rbx; @@ -273,6 +256,8 @@ _gcry_cast5_amd64_decrypt_block: popq %rbx; popq %rbp; + + EXIT_SYSV_FUNC ret; ELF(.size _gcry_cast5_amd64_decrypt_block,.-_gcry_cast5_amd64_decrypt_block;) @@ -444,6 +429,7 @@ _gcry_cast5_amd64_ctr_enc: * %rdx: src (8 blocks) * %rcx: iv (big endian, 64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 pushq %rbp; pushq %rbx; @@ -489,6 +475,8 @@ _gcry_cast5_amd64_ctr_enc: popq %r12; popq %rbx; popq %rbp; + + EXIT_SYSV_FUNC ret ELF(.size _gcry_cast5_amd64_ctr_enc,.-_gcry_cast5_amd64_ctr_enc;) @@ -502,6 +490,7 @@ _gcry_cast5_amd64_cbc_dec: * %rdx: src (8 blocks) * %rcx: iv (64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 pushq %rbp; pushq %rbx; @@ -542,6 +531,8 @@ _gcry_cast5_amd64_cbc_dec: popq %r12; popq %rbx; popq %rbp; + + EXIT_SYSV_FUNC ret; ELF(.size _gcry_cast5_amd64_cbc_dec,.-_gcry_cast5_amd64_cbc_dec;) @@ -556,6 +547,7 @@ _gcry_cast5_amd64_cfb_dec: * %rdx: src (8 blocks) * %rcx: iv (64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 pushq %rbp; pushq %rbx; @@ -597,6 +589,8 @@ _gcry_cast5_amd64_cfb_dec: popq %r12; popq %rbx; popq %rbp; + + EXIT_SYSV_FUNC ret; ELF(.size _gcry_cast5_amd64_cfb_dec,.-_gcry_cast5_amd64_cfb_dec;) diff --git a/cipher/cast5.c b/cipher/cast5.c index 94dcee7..d23882b 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -373,72 +373,34 @@ extern void _gcry_cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, extern void _gcry_cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv); -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS -static inline void -call_sysv_fn (const void *fn, const void *arg1, const void *arg2, - const void *arg3, const void *arg4) -{ - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - asm volatile ("callq *%0\n\t" - : "+a" (fn), - "+D" (arg1), - "+S" (arg2), - "+d" (arg3), - "+c" (arg4) - : - : "cc", "memory", "r8", "r9", "r10", "r11"); -} -#endif - static void do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_cast5_amd64_encrypt_block, context, outbuf, inbuf, NULL); -#else _gcry_cast5_amd64_encrypt_block (context, outbuf, inbuf); -#endif } static void do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_cast5_amd64_decrypt_block, context, outbuf, inbuf, NULL); -#else _gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf); -#endif } static void cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_cast5_amd64_ctr_enc, ctx, out, in, ctr); -#else _gcry_cast5_amd64_ctr_enc (ctx, out, in, ctr); -#endif } static void cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_cast5_amd64_cbc_dec, ctx, out, in, iv); -#else _gcry_cast5_amd64_cbc_dec (ctx, out, in, iv); -#endif } static void cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_cast5_amd64_cfb_dec, ctx, out, in, iv); -#else _gcry_cast5_amd64_cfb_dec (ctx, out, in, iv); -#endif } static unsigned int diff --git a/cipher/des-amd64.S b/cipher/des-amd64.S index 1b7cfba..f25573d 100644 --- a/cipher/des-amd64.S +++ b/cipher/des-amd64.S @@ -23,17 +23,7 @@ #if defined(USE_DES) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) -#ifdef __PIC__ -# define RIP (%rip) -#else -# define RIP -#endif - -#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS -# define ELF(...) __VA_ARGS__ -#else -# define ELF(...) /*_*/ -#endif +#include "asm-common-amd64.h" .text @@ -200,6 +190,8 @@ _gcry_3des_amd64_crypt_block: * %rsi: dst * %rdx: src */ + ENTER_SYSV_FUNC_PARAMS_0_4 + pushq %rbp; pushq %rbx; pushq %r12; @@ -208,7 +200,7 @@ _gcry_3des_amd64_crypt_block: pushq %r15; pushq %rsi; /*dst*/ - leaq .L_s1 RIP, SBOXES; + leaq .L_s1 rRIP, SBOXES; read_block(%rdx, RL0, RR0); initial_permutation(RL0, RR0); @@ -277,6 +269,7 @@ _gcry_3des_amd64_crypt_block: popq %rbx; popq %rbp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_3des_amd64_crypt_block,.-_gcry_3des_amd64_crypt_block;) @@ -473,7 +466,7 @@ _gcry_3des_amd64_crypt_blk3: * RR0d, RL0d, RR1d, RL1d, RR2d, RL2d: 3 output blocks */ - leaq .L_s1 RIP, SBOXES; + leaq .L_s1 rRIP, SBOXES; initial_permutation3(RL, RR); @@ -547,6 +540,7 @@ _gcry_3des_amd64_cbc_dec: * %rdx: src (3 blocks) * %rcx: iv (64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 pushq %rbp; pushq %rbx; @@ -610,6 +604,7 @@ _gcry_3des_amd64_cbc_dec: popq %rbx; popq %rbp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;) @@ -623,6 +618,7 @@ _gcry_3des_amd64_ctr_enc: * %rdx: src (3 blocks) * %rcx: iv (64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 pushq %rbp; pushq %rbx; @@ -688,6 +684,7 @@ _gcry_3des_amd64_ctr_enc: popq %rbx; popq %rbp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;) @@ -701,6 +698,8 @@ _gcry_3des_amd64_cfb_dec: * %rdx: src (3 blocks) * %rcx: iv (64bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 + pushq %rbp; pushq %rbx; pushq %r12; @@ -763,6 +762,8 @@ _gcry_3des_amd64_cfb_dec: popq %r12; popq %rbx; popq %rbp; + + EXIT_SYSV_FUNC ret; ELF(.size _gcry_3des_amd64_cfb_dec,.-_gcry_3des_amd64_cfb_dec;) diff --git a/cipher/des.c b/cipher/des.c index 5c99f50..7801b08 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -772,23 +772,6 @@ extern void _gcry_3des_amd64_cfb_dec(const void *keys, byte *out, #define TRIPLEDES_ECB_BURN_STACK (8 * sizeof(void *)) -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS -static inline void -call_sysv_fn (const void *fn, const void *arg1, const void *arg2, - const void *arg3, const void *arg4) -{ - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - asm volatile ("callq *%0\n\t" - : "+a" (fn), - "+D" (arg1), - "+S" (arg2), - "+d" (arg3), - "+c" (arg4) - : - : "cc", "memory", "r8", "r9", "r10", "r11"); -} -#endif /* * Electronic Codebook Mode Triple-DES encryption/decryption of data @@ -803,11 +786,7 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_3des_amd64_crypt_block, keys, to, from, NULL); -#else _gcry_3des_amd64_crypt_block(keys, to, from); -#endif return 0; } @@ -815,31 +794,19 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, static inline void tripledes_amd64_ctr_enc(const void *keys, byte *out, const byte *in, byte *ctr) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_3des_amd64_ctr_enc, keys, out, in, ctr); -#else _gcry_3des_amd64_ctr_enc(keys, out, in, ctr); -#endif } static inline void tripledes_amd64_cbc_dec(const void *keys, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_3des_amd64_cbc_dec, keys, out, in, iv); -#else _gcry_3des_amd64_cbc_dec(keys, out, in, iv); -#endif } static inline void tripledes_amd64_cfb_dec(const void *keys, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn (_gcry_3des_amd64_cfb_dec, keys, out, in, iv); -#else _gcry_3des_amd64_cfb_dec(keys, out, in, iv); -#endif } #else /*USE_AMD64_ASM*/ diff --git a/cipher/rijndael-amd64.S b/cipher/rijndael-amd64.S index b149e94..798ff51 100644 --- a/cipher/rijndael-amd64.S +++ b/cipher/rijndael-amd64.S @@ -23,17 +23,7 @@ #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_AES) -#ifdef __PIC__ -# define RIP (%rip) -#else -# define RIP -#endif - -#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS -# define ELF(...) __VA_ARGS__ -#else -# define ELF(...) /*_*/ -#endif +#include "asm-common-amd64.h" .text @@ -222,6 +212,8 @@ _gcry_aes_amd64_encrypt_block: * %ecx: number of rounds.. 10, 12 or 14 * %r8: encryption tables */ + ENTER_SYSV_FUNC_PARAMS_5 + subq $(5 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); movl %ecx, (1 * 8)(%rsp); @@ -265,6 +257,8 @@ _gcry_aes_amd64_encrypt_block: addq $(5 * 8), %rsp; movl $(6 * 8), %eax; + + EXIT_SYSV_FUNC ret; .align 4 @@ -382,6 +376,8 @@ _gcry_aes_amd64_decrypt_block: * %ecx: number of rounds.. 10, 12 or 14 * %r8: decryption tables */ + ENTER_SYSV_FUNC_PARAMS_5 + subq $(5 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); movl %ecx, (1 * 8)(%rsp); @@ -426,6 +422,8 @@ _gcry_aes_amd64_decrypt_block: addq $(5 * 8), %rsp; movl $(6 * 8), %eax; + + EXIT_SYSV_FUNC ret; .align 4 diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 548bfa0..df1363f 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -740,27 +740,8 @@ do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { #ifdef USE_AMD64_ASM -# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); -# else - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - const void *key = ctx->keyschenc; - uintptr_t rounds = ctx->rounds; - uintptr_t ret; - asm volatile ("movq %[encT], %%r8\n\t" - "callq *%[ret]\n\t" - : [ret] "=a" (ret), - "+D" (key), - "+S" (bx), - "+d" (ax), - "+c" (rounds) - : "0" (_gcry_aes_amd64_encrypt_block), - [encT] "r" (encT) - : "cc", "memory", "r8", "r9", "r10", "r11"); - return ret; -# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */ #elif defined(USE_ARM_ASM) return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); #else @@ -1123,27 +1104,8 @@ do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { #ifdef USE_AMD64_ASM -# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, &dec_tables); -# else - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - const void *key = ctx->keyschdec; - uintptr_t rounds = ctx->rounds; - uintptr_t ret; - asm volatile ("movq %[dectabs], %%r8\n\t" - "callq *%[ret]\n\t" - : [ret] "=a" (ret), - "+D" (key), - "+S" (bx), - "+d" (ax), - "+c" (rounds) - : "0" (_gcry_aes_amd64_decrypt_block), - [dectabs] "r" (&dec_tables) - : "cc", "memory", "r8", "r9", "r10", "r11"); - return ret; -# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */ #elif defined(USE_ARM_ASM) return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, &dec_tables); diff --git a/cipher/twofish-amd64.S b/cipher/twofish-amd64.S index aa964e0..7a83646 100644 --- a/cipher/twofish-amd64.S +++ b/cipher/twofish-amd64.S @@ -23,17 +23,7 @@ #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_TWOFISH) -#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS -# define ELF(...) __VA_ARGS__ -#else -# define ELF(...) /*_*/ -#endif - -#ifdef __PIC__ -# define RIP %rip -#else -# define RIP -#endif +#include "asm-common-amd64.h" .text @@ -181,6 +171,8 @@ _gcry_twofish_amd64_encrypt_block: * %rsi: dst * %rdx: src */ + ENTER_SYSV_FUNC_PARAMS_0_4 + subq $(3 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); movq %rbp, (1 * 8)(%rsp); @@ -211,6 +203,7 @@ _gcry_twofish_amd64_encrypt_block: movq (1 * 8)(%rsp), %rbp; addq $(3 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;) @@ -224,6 +217,8 @@ _gcry_twofish_amd64_decrypt_block: * %rsi: dst * %rdx: src */ + ENTER_SYSV_FUNC_PARAMS_0_4 + subq $(3 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); movq %rbp, (1 * 8)(%rsp); @@ -254,6 +249,7 @@ _gcry_twofish_amd64_decrypt_block: movq (1 * 8)(%rsp), %rbp; addq $(3 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;) @@ -530,6 +526,8 @@ _gcry_twofish_amd64_ctr_enc: * %rdx: src (3 blocks) * %rcx: iv (big endian, 128bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 + subq $(8 * 8), %rsp; movq %rbp, (0 * 8)(%rsp); movq %rbx, (1 * 8)(%rsp); @@ -599,6 +597,7 @@ _gcry_twofish_amd64_ctr_enc: movq (5 * 8)(%rsp), %r15; addq $(8 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_ctr_enc,.-_gcry_twofish_amd64_ctr_enc;) @@ -612,6 +611,8 @@ _gcry_twofish_amd64_cbc_dec: * %rdx: src (3 blocks) * %rcx: iv (128bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 + subq $(9 * 8), %rsp; movq %rbp, (0 * 8)(%rsp); movq %rbx, (1 * 8)(%rsp); @@ -665,6 +666,7 @@ _gcry_twofish_amd64_cbc_dec: movq (5 * 8)(%rsp), %r15; addq $(9 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_cbc_dec,.-_gcry_twofish_amd64_cbc_dec;) @@ -678,6 +680,8 @@ _gcry_twofish_amd64_cfb_dec: * %rdx: src (3 blocks) * %rcx: iv (128bit) */ + ENTER_SYSV_FUNC_PARAMS_0_4 + subq $(8 * 8), %rsp; movq %rbp, (0 * 8)(%rsp); movq %rbx, (1 * 8)(%rsp); @@ -731,6 +735,7 @@ _gcry_twofish_amd64_cfb_dec: movq (5 * 8)(%rsp), %r15; addq $(8 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;) @@ -746,6 +751,8 @@ _gcry_twofish_amd64_ocb_enc: * %r8 : checksum * %r9 : L pointers (void *L[3]) */ + ENTER_SYSV_FUNC_PARAMS_6 + subq $(8 * 8), %rsp; movq %rbp, (0 * 8)(%rsp); movq %rbx, (1 * 8)(%rsp); @@ -838,6 +845,7 @@ _gcry_twofish_amd64_ocb_enc: movq (5 * 8)(%rsp), %r15; addq $(8 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_ocb_enc,.-_gcry_twofish_amd64_ocb_enc;) @@ -853,6 +861,8 @@ _gcry_twofish_amd64_ocb_dec: * %r8 : checksum * %r9 : L pointers (void *L[3]) */ + ENTER_SYSV_FUNC_PARAMS_6 + subq $(8 * 8), %rsp; movq %rbp, (0 * 8)(%rsp); movq %rbx, (1 * 8)(%rsp); @@ -953,6 +963,7 @@ _gcry_twofish_amd64_ocb_dec: movq (5 * 8)(%rsp), %r15; addq $(8 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_ocb_dec,.-_gcry_twofish_amd64_ocb_dec;) @@ -967,6 +978,8 @@ _gcry_twofish_amd64_ocb_auth: * %rcx: checksum * %r8 : L pointers (void *L[3]) */ + ENTER_SYSV_FUNC_PARAMS_5 + subq $(8 * 8), %rsp; movq %rbp, (0 * 8)(%rsp); movq %rbx, (1 * 8)(%rsp); @@ -1039,6 +1052,7 @@ _gcry_twofish_amd64_ocb_auth: movq (5 * 8)(%rsp), %r15; addq $(8 * 8), %rsp; + EXIT_SYSV_FUNC ret; ELF(.size _gcry_twofish_amd64_ocb_auth,.-_gcry_twofish_amd64_ocb_auth;) diff --git a/cipher/twofish.c b/cipher/twofish.c index 942e8d4..48feaae 100644 --- a/cipher/twofish.c +++ b/cipher/twofish.c @@ -829,145 +829,58 @@ extern void _gcry_twofish_amd64_ocb_auth(const TWOFISH_context *ctx, const byte *abuf, byte *offset, byte *checksum, const u64 Ls[3]); -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS -static inline void -call_sysv_fn (const void *fn, const void *arg1, const void *arg2, - const void *arg3, const void *arg4) -{ - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - asm volatile ("callq *%0\n\t" - : "+a" (fn), - "+D" (arg1), - "+S" (arg2), - "+d" (arg3), - "+c" (arg4) - : - : "cc", "memory", "r8", "r9", "r10", "r11"); -} - -static inline void -call_sysv_fn5 (const void *fn, const void *arg1, const void *arg2, - const void *arg3, const void *arg4, const void *arg5) -{ - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - asm volatile ("movq %[arg5], %%r8\n\t" - "callq *%0\n\t" - : "+a" (fn), - "+D" (arg1), - "+S" (arg2), - "+d" (arg3), - "+c" (arg4) - : [arg5] "g" (arg5) - : "cc", "memory", "r8", "r9", "r10", "r11"); -} - -static inline void -call_sysv_fn6 (const void *fn, const void *arg1, const void *arg2, - const void *arg3, const void *arg4, const void *arg5, - const void *arg6) -{ - /* Call SystemV ABI function without storing non-volatile XMM registers, - * as target function does not use vector instruction sets. */ - asm volatile ("movq %[arg5], %%r8\n\t" - "movq %[arg6], %%r9\n\t" - "callq *%0\n\t" - : "+a" (fn), - "+D" (arg1), - "+S" (arg2), - "+d" (arg3), - "+c" (arg4) - : [arg5] "g" (arg5), - [arg6] "g" (arg6) - : "cc", "memory", "r8", "r9", "r10", "r11"); -} -#endif - static inline void twofish_amd64_encrypt_block(const TWOFISH_context *c, byte *out, const byte *in) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn(_gcry_twofish_amd64_encrypt_block, c, out, in, NULL); -#else _gcry_twofish_amd64_encrypt_block(c, out, in); -#endif } static inline void twofish_amd64_decrypt_block(const TWOFISH_context *c, byte *out, const byte *in) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn(_gcry_twofish_amd64_decrypt_block, c, out, in, NULL); -#else _gcry_twofish_amd64_decrypt_block(c, out, in); -#endif } static inline void twofish_amd64_ctr_enc(const TWOFISH_context *c, byte *out, const byte *in, byte *ctr) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn(_gcry_twofish_amd64_ctr_enc, c, out, in, ctr); -#else _gcry_twofish_amd64_ctr_enc(c, out, in, ctr); -#endif } static inline void twofish_amd64_cbc_dec(const TWOFISH_context *c, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn(_gcry_twofish_amd64_cbc_dec, c, out, in, iv); -#else _gcry_twofish_amd64_cbc_dec(c, out, in, iv); -#endif } static inline void twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out, const byte *in, byte *iv) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn(_gcry_twofish_amd64_cfb_dec, c, out, in, iv); -#else _gcry_twofish_amd64_cfb_dec(c, out, in, iv); -#endif } static inline void twofish_amd64_ocb_enc(const TWOFISH_context *ctx, byte *out, const byte *in, byte *offset, byte *checksum, const u64 Ls[3]) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn6(_gcry_twofish_amd64_ocb_enc, ctx, out, in, offset, checksum, Ls); -#else _gcry_twofish_amd64_ocb_enc(ctx, out, in, offset, checksum, Ls); -#endif } static inline void twofish_amd64_ocb_dec(const TWOFISH_context *ctx, byte *out, const byte *in, byte *offset, byte *checksum, const u64 Ls[3]) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn6(_gcry_twofish_amd64_ocb_dec, ctx, out, in, offset, checksum, Ls); -#else _gcry_twofish_amd64_ocb_dec(ctx, out, in, offset, checksum, Ls); -#endif } static inline void twofish_amd64_ocb_auth(const TWOFISH_context *ctx, const byte *abuf, byte *offset, byte *checksum, const u64 Ls[3]) { -#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS - call_sysv_fn5(_gcry_twofish_amd64_ocb_auth, ctx, abuf, offset, checksum, Ls); -#else _gcry_twofish_amd64_ocb_auth(ctx, abuf, offset, checksum, Ls); -#endif } #elif defined(USE_ARM_ASM) commit 135250e3060e79be698d4f36a819aa8a880789f8 Author: Jussi Kivilinna Date: Sat Jan 6 20:26:52 2018 +0200 Make BMI2 inline assembly check more robust * configure.ac (gcry_cv_gcc_inline_asm_bmi2): New assembly test. -- Use actual assembly snippets from keccak.c to check that compiler has proper support for used BMI2 instructions. GnuPG-bug-id: 3408 Signed-off-by: Jussi Kivilinna diff --git a/configure.ac b/configure.ac index 42cd4c2..aaf3c82 100644 --- a/configure.ac +++ b/configure.ac @@ -1403,8 +1403,15 @@ AC_CACHE_CHECK([whether GCC inline assembler supports BMI2 instructions], else gcry_cv_gcc_inline_asm_bmi2=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( - [[void a(void) { - __asm__("rorxl \$23, %%eax, %%edx\\n\\t":::"memory"); + [[unsigned int a(unsigned int x, unsigned int y) { + unsigned int tmp1, tmp2; + asm ("rorxl %2, %1, %0" + : "=r" (tmp1) + : "rm0" (x), "J" (32 - ((23) & 31))); + asm ("andnl %2, %1, %0" + : "=r" (tmp2) + : "r0" (x), "rm" (y)); + return tmp1 + tmp2; }]])], [gcry_cv_gcc_inline_asm_bmi2=yes]) fi]) ----------------------------------------------------------------------- Summary of changes: cipher/Makefile.am | 1 + cipher/arcfour-amd64.S | 8 ++-- cipher/arcfour.c | 14 ------ cipher/asm-common-amd64.h | 90 ++++++++++++++++++++++++++++++++++++++ cipher/blowfish-amd64.S | 24 ++++++++--- cipher/blowfish.c | 44 ------------------- cipher/cast5-amd64.S | 42 ++++++++---------- cipher/cast5.c | 38 ---------------- cipher/des-amd64.S | 27 ++++++------ cipher/des.c | 33 -------------- cipher/rijndael-amd64.S | 20 ++++----- cipher/rijndael-ssse3-amd64-asm.S | 31 ++++++++----- cipher/rijndael-ssse3-amd64.c | 91 ++++++--------------------------------- cipher/rijndael.c | 38 ---------------- cipher/twofish-amd64.S | 36 +++++++++++----- cipher/twofish.c | 87 ------------------------------------- configure.ac | 11 ++++- 17 files changed, 223 insertions(+), 412 deletions(-) create mode 100644 cipher/asm-common-amd64.h hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 18 13:45:10 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Jan 2018 13:45:10 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-10-ge1e35db Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via e1e35db510c9222e7a7dc208c2e49df556954170 (commit) from 6fb5713f4a6976900cc70c140e61043b6ef688d1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e1e35db510c9222e7a7dc208c2e49df556954170 Author: Werner Koch Date: Thu Jan 18 13:38:23 2018 +0100 gpg: Fix the use of future-default with --quick-add-key. * g10/keygen.c (parse_key_parameter_part): Add arg clear_cert. (parse_key_parameter_string): Add arg suggested_use and implement fallback. Change callers to pass 0 for new arg. (parse_algo_usage_expire): Pass the parsed USAGESTR to parse_key_parameter_string so that it can use it in case a subkey is to be created. -- The problem here was that future-default gives the primary and subkey algorithm. However, when using future-default for adding a key, the second part was always used which is for encryption. If the caller now wanted to create a signing subkey using the future-default parameters this did not worked. gpg --batch --passphrase "" --quick-add-key FPR future-default encr aready worked as did gpg --batch --passphrase "" --quick-add-key FPR ed25519 sign but gpg --batch --passphrase "" --quick-add-key FPR future-default sign does only work with this fix. GnuPG-bug-id: 3747 Signed-off-by: Werner Koch diff --git a/g10/keygen.c b/g10/keygen.c index 01f3de0..8de6538 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2895,9 +2895,11 @@ generate_user_id (KBNODE keyblock, const char *uidstr) * success is returned. On error an error code is returned. Note * that STRING may be modified by this function. NULL may be passed * for any parameter. FOR_SUBKEY shall be true if this is used as a + * subkey. If CLEAR_CERT is set a default CERT usage will be cleared; + * this is useful if for example the default algorithm is used for a * subkey. */ static gpg_error_t -parse_key_parameter_part (char *string, int for_subkey, +parse_key_parameter_part (char *string, int for_subkey, int clear_cert, int *r_algo, unsigned int *r_size, unsigned int *r_keyuse, char const **r_curve) @@ -3048,6 +3050,10 @@ parse_key_parameter_part (char *string, int for_subkey, if (!for_subkey) keyuse |= PUBKEY_USAGE_CERT; + /* But if requested remove th cert usage. */ + if (clear_cert) + keyuse &= ~PUBKEY_USAGE_CERT; + /* Check that usage is actually possible. */ if (/**/((keyuse & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH|PUBKEY_USAGE_CERT)) && !pubkey_get_nsig (algo)) @@ -3119,14 +3125,16 @@ parse_key_parameter_part (char *string, int for_subkey, * -1 := Both parts * 0 := Only the part of the primary key * 1 := If there is one part parse that one, if there are - * two parts parse the second part. Always return - * in the args for the primary key (R_ALGO,....). + * two parts parse the part which best matches the + * SUGGESTED_USE or in case that can't be evaluated the second part. + * Always return using the args for the primary key (R_ALGO,....). * */ gpg_error_t parse_key_parameter_string (const char *string, int part, + unsigned int suggested_use, int *r_algo, unsigned int *r_size, - unsigned *r_keyuse, + unsigned int *r_keyuse, char const **r_curve, int *r_subalgo, unsigned int *r_subsize, unsigned *r_subkeyuse, @@ -3165,18 +3173,31 @@ parse_key_parameter_string (const char *string, int part, *secondary++ = 0; if (part == -1 || part == 0) { - err = parse_key_parameter_part (primary, 0, r_algo, r_size, + err = parse_key_parameter_part (primary, 0, 0, r_algo, r_size, r_keyuse, r_curve); if (!err && part == -1) - err = parse_key_parameter_part (secondary, 1, r_subalgo, r_subsize, + err = parse_key_parameter_part (secondary, 1, 0, r_subalgo, r_subsize, r_subkeyuse, r_subcurve); } else if (part == 1) { /* If we have SECONDARY, use that part. If there is only one - * part consider this to be the subkey algo. */ - err = parse_key_parameter_part (secondary? secondary : primary, 1, - r_algo, r_size, r_keyuse, r_curve); + * part consider this to be the subkey algo. In case a + * SUGGESTED_USE has been given and the usage of the secondary + * part does not match SUGGESTED_USE try again using the primary + * part. Noet thar when falling back to the primary key we need + * to force clearing the cert usage. */ + if (secondary) + { + err = parse_key_parameter_part (secondary, 1, 0, + r_algo, r_size, r_keyuse, r_curve); + if (!err && suggested_use && r_keyuse && !(suggested_use & *r_keyuse)) + err = parse_key_parameter_part (primary, 1, 1 /*(clear cert)*/, + r_algo, r_size, r_keyuse, r_curve); + } + else + err = parse_key_parameter_part (primary, 1, 0, + r_algo, r_size, r_keyuse, r_curve); } xfree (primary); @@ -3263,7 +3284,7 @@ get_parameter_algo( struct para_data_s *para, enum para_name key, * for the curve etc. That is a ugly but demanded for backward * compatibility with the batch key generation. It would be * better to make full use of parse_key_parameter_string. */ - parse_key_parameter_string (NULL, 0, + parse_key_parameter_string (NULL, 0, 0, &i, NULL, NULL, NULL, NULL, NULL, NULL, NULL); @@ -3997,7 +4018,7 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr, unsigned int keyuse, subkeyuse; const char *curve, *subcurve; - err = parse_key_parameter_string (algostr, -1, + err = parse_key_parameter_string (algostr, -1, 0, &algo, &size, &keyuse, &curve, &subalgo, &subsize, &subkeyuse, &subcurve); @@ -4376,7 +4397,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, #endif , "--full-generate-key" ); - err = parse_key_parameter_string (NULL, -1, + err = parse_key_parameter_string (NULL, -1, 0, &algo, &size, &keyuse, &curve, &subalgo, &subsize, &subkeyuse, &subcurve); @@ -4923,6 +4944,7 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey, } err = parse_key_parameter_string (algostr, for_subkey? 1 : 0, + usagestr? parse_usagestr (usagestr):0, &algo, &nbits, &use, &curve, NULL, NULL, NULL, NULL); if (err) ----------------------------------------------------------------------- Summary of changes: g10/keygen.c | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 19 09:28:05 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 19 Jan 2018 09:28:05 +0100 Subject: [git] gnupg-doc - branch, master, updated. f8a54305c4e3354fba02f9b2da5b9683d92a6c4c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via f8a54305c4e3354fba02f9b2da5b9683d92a6c4c (commit) from 76802d1db0d7ef9bf9376907d86e75b5edd78ba2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f8a54305c4e3354fba02f9b2da5b9683d92a6c4c Author: Werner Koch Date: Fri Jan 19 09:22:07 2018 +0100 web: Add La Boussole as first privacy training entity. diff --git a/web/service.org b/web/service.org index ee061b1..07f533a 100644 --- a/web/service.org +++ b/web/service.org @@ -24,7 +24,15 @@ provide this list to enable you to contact service providers. The companies listed here provide mainly non-technical training and consulting on secure communication. - /none so far/ + - [[https://laboussole.coop][La Boussole]], Ile-de-France, France :: La Boussole is a cooperative + organization based in France. It brings together academic + scholars and trainers who run training sessions on digital + issues (privacy protection, environmental impact, social and + political insights of IT, and the promotion of commons), but + also on media, cooperative teamwork, and fight against + discrimination. Our pedagogy is rooted in non-formal education + (so-called "?ducation populaire"), which aims at accompanying + individuals and groups towards emancipation. ** Technical support ----------------------------------------------------------------------- Summary of changes: web/service.org | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jan 20 21:16:46 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sat, 20 Jan 2018 21:16:46 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-36-g93503c1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 93503c127a52c1f6a193750e2bf181a744ba3e6b (commit) from c3d60acc3ab5c6d60c2258882175bf31351cc998 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 93503c127a52c1f6a193750e2bf181a744ba3e6b Author: Jussi Kivilinna Date: Sat Jan 20 22:05:19 2018 +0200 Add ARMv8/CE acceleration for AES-XTS * cipher/rijndael-armv8-aarch32-ce.S (_gcry_aes_xts_enc_armv8_ce) (_gcry_aes_xts_dec_armv8_ce): New. * cipher/rijndael-armv8-aarch64-ce.S (_gcry_aes_xts_enc_armv8_ce) (_gcry_aes_xts_dec_armv8_ce): New. * cipher/rijndael-armv8-ce.c (_gcry_aes_xts_enc_armv8_ce) (_gcry_aes_xts_dec_armv8_ce, xts_crypt_fn_t) (_gcry_aes_armv8_ce_xts_crypt): New. * cipher/rijndael.c (_gcry_aes_armv8_ce_xts_crypt): New. (_gcry_aes_xts_crypt) [USE_ARM_CE]: New. -- Benchmark on Cortex-A53 (AArch64, 1152 Mhz): Before: AES | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 4.88 ns/B 195.5 MiB/s 5.62 c/B XTS dec | 4.94 ns/B 192.9 MiB/s 5.70 c/B = AES192 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 5.55 ns/B 171.8 MiB/s 6.39 c/B XTS dec | 5.61 ns/B 169.9 MiB/s 6.47 c/B = AES256 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 6.22 ns/B 153.3 MiB/s 7.17 c/B XTS dec | 6.29 ns/B 151.7 MiB/s 7.24 c/B = After (~2.6x faster): AES | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 1.83 ns/B 520.9 MiB/s 2.11 c/B XTS dec | 1.82 ns/B 524.9 MiB/s 2.09 c/B = AES192 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 1.97 ns/B 483.3 MiB/s 2.27 c/B XTS dec | 1.96 ns/B 486.9 MiB/s 2.26 c/B = AES256 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 2.11 ns/B 450.9 MiB/s 2.44 c/B XTS dec | 2.10 ns/B 453.8 MiB/s 2.42 c/B = Benchmark on Cortex-A53 (AArch32, 1152 Mhz): Before: AES | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 6.52 ns/B 146.2 MiB/s 7.51 c/B XTS dec | 6.57 ns/B 145.2 MiB/s 7.57 c/B = AES192 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 7.10 ns/B 134.3 MiB/s 8.18 c/B XTS dec | 7.11 ns/B 134.2 MiB/s 8.19 c/B = AES256 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 7.30 ns/B 130.7 MiB/s 8.41 c/B XTS dec | 7.38 ns/B 129.3 MiB/s 8.50 c/B = After (~2.7x faster): Cipher: AES | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 2.33 ns/B 409.6 MiB/s 2.68 c/B XTS dec | 2.35 ns/B 405.3 MiB/s 2.71 c/B = AES192 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 2.53 ns/B 377.6 MiB/s 2.91 c/B XTS dec | 2.54 ns/B 375.5 MiB/s 2.93 c/B = AES256 | nanosecs/byte mebibytes/sec cycles/byte XTS enc | 2.75 ns/B 346.8 MiB/s 3.17 c/B XTS dec | 2.76 ns/B 345.2 MiB/s 3.18 c/B = Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael-armv8-aarch32-ce.S b/cipher/rijndael-armv8-aarch32-ce.S index 5c8fa3c..66440bd 100644 --- a/cipher/rijndael-armv8-aarch32-ce.S +++ b/cipher/rijndael-armv8-aarch32-ce.S @@ -1517,6 +1517,317 @@ _gcry_aes_ocb_auth_armv8_ce: .size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce; + +/* + * void _gcry_aes_xts_enc_armv8_ce (const void *keysched, + * unsigned char *outbuf, + * const unsigned char *inbuf, + * unsigned char *iv, unsigned int nrounds); + */ + +.align 3 +.globl _gcry_aes_xts_enc_armv8_ce +.type _gcry_aes_xts_enc_armv8_ce,%function; +_gcry_aes_xts_enc_armv8_ce: + /* input: + * r0: keysched + * r1: outbuf + * r2: inbuf + * r3: iv + * %st+0: nblocks => r4 + * %st+4: nrounds => r5 + */ + + vpush {q4-q7} + push {r4-r12,lr} /* 4*16 + 4*10 = 104b */ + ldr r4, [sp, #(104+0)] + ldr r5, [sp, #(104+4)] + cmp r4, #0 + beq .Lxts_enc_skip + + cmp r5, #12 + + vld1.8 {q0}, [r3] /* load tweak */ + mov r7, #0x87; + + aes_preload_keys(r0, r6); + + beq .Lxts_enc_entry_192 + bhi .Lxts_enc_entry_256 + +#define CTR_XTS(bits, ...) \ + .Lxts_enc_entry_##bits: \ + cmp r4, #4; \ + blo .Lxts_enc_loop_##bits; \ + \ + .Lxts_enc_loop4_##bits: \ + sub r4, r4, #4; \ + veor q9, q9, q9; \ + \ + vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \ + veor q1, q1, q0; \ + cmp r4, #4; \ + vmov.u32 d18[0], r7; \ + vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \ + veor q2, q2, q0; \ + vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + veor q3, q3, q0; \ + vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + veor q4, q4, q0; \ + vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \ + sub r1, r1, #48; \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \ + \ + vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \ + veor q1, q1, q8; \ + veor q2, q2, q9; \ + vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \ + sub r1, r1, #32; \ + veor q3, q3, q8; \ + veor q4, q4, q9; \ + vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \ + vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \ + \ + bhs .Lxts_enc_loop4_##bits; \ + cmp r4, #0; \ + beq .Lxts_enc_done; \ + \ + .Lxts_enc_loop_##bits: \ + \ + vld1.8 {q1}, [r2]!; /* load ciphertext */ \ + \ + veor q9, q9, q9; \ + veor q1, q1, q0; \ + vmov.u32 d18[0], r7; \ + vmov q2, q0; \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + subs r4, r4, #1; \ + \ + do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__); \ + \ + veor q1, q1, q2; \ + vst1.8 {q1}, [r1]!; /* store plaintext */ \ + \ + bne .Lxts_enc_loop_##bits; \ + b .Lxts_enc_done; + + CTR_XTS(128re, r0, r6) + CTR_XTS(192, r0, r6) + CTR_XTS(256, r0, r6) + +#undef CTR_XTS + +.Lxts_enc_done: + vst1.8 {q0}, [r3] /* store tweak */ + + CLEAR_REG(q0) + CLEAR_REG(q1) + CLEAR_REG(q2) + CLEAR_REG(q3) + CLEAR_REG(q8) + CLEAR_REG(q9) + CLEAR_REG(q10) + CLEAR_REG(q11) + CLEAR_REG(q12) + CLEAR_REG(q13) + CLEAR_REG(q14) + +.Lxts_enc_skip: + pop {r4-r12,lr} + vpop {q4-q7} + bx lr +.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce; + + +/* + * void _gcry_aes_xts_dec_armv8_ce (const void *keysched, + * unsigned char *outbuf, + * const unsigned char *inbuf, + * unsigned char *iv, unsigned int nrounds); + */ + +.align 3 +.globl _gcry_aes_xts_dec_armv8_ce +.type _gcry_aes_xts_dec_armv8_ce,%function; +_gcry_aes_xts_dec_armv8_ce: + /* input: + * r0: keysched + * r1: outbuf + * r2: inbuf + * r3: iv + * %st+0: nblocks => r4 + * %st+4: nrounds => r5 + */ + + vpush {q4-q7} + push {r4-r12,lr} /* 4*16 + 4*10 = 104b */ + ldr r4, [sp, #(104+0)] + ldr r5, [sp, #(104+4)] + cmp r4, #0 + beq .Lxts_dec_skip + + cmp r5, #12 + + vld1.8 {q0}, [r3] /* load tweak */ + mov r7, #0x87; + + aes_preload_keys(r0, r6); + + beq .Lxts_dec_entry_192 + bhi .Lxts_dec_entry_256 + +#define CTR_XTS(bits, ...) \ + .Lxts_dec_entry_##bits: \ + cmp r4, #4; \ + blo .Lxts_dec_loop_##bits; \ + \ + .Lxts_dec_loop4_##bits: \ + sub r4, r4, #4; \ + veor q9, q9, q9; \ + \ + vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \ + veor q1, q1, q0; \ + cmp r4, #4; \ + vmov.u32 d18[0], r7; \ + vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \ + veor q2, q2, q0; \ + vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + veor q3, q3, q0; \ + vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + veor q4, q4, q0; \ + vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \ + sub r1, r1, #48; \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + \ + do_aes_4_##bits(d, imc, q1, q2, q3, q4, ##__VA_ARGS__); \ + \ + vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \ + veor q1, q1, q8; \ + veor q2, q2, q9; \ + vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \ + sub r1, r1, #32; \ + veor q3, q3, q8; \ + veor q4, q4, q9; \ + vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \ + vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \ + \ + bhs .Lxts_dec_loop4_##bits; \ + cmp r4, #0; \ + beq .Lxts_dec_done; \ + \ + .Lxts_dec_loop_##bits: \ + \ + vld1.8 {q1}, [r2]!; /* load ciphertext */ \ + \ + veor q9, q9, q9; \ + veor q1, q1, q0; \ + vmov.u32 d18[0], r7; \ + vmov q2, q0; \ + \ + vshr.s64 d16, d1, #63; \ + vshr.u64 d17, d0, #63; \ + vadd.u64 q0, q0, q0; \ + vand d16, d16, d18; \ + veor q0, q0, q8; \ + subs r4, r4, #1; \ + \ + do_aes_one##bits(d, imc, q1, q1, ##__VA_ARGS__); \ + \ + veor q1, q1, q2; \ + vst1.8 {q1}, [r1]!; /* store plaintext */ \ + \ + bne .Lxts_dec_loop_##bits; \ + b .Lxts_dec_done; + + CTR_XTS(128re, r0, r6) + CTR_XTS(192, r0, r6) + CTR_XTS(256, r0, r6) + +#undef CTR_XTS + +.Lxts_dec_done: + vst1.8 {q0}, [r3] /* store tweak */ + + CLEAR_REG(q0) + CLEAR_REG(q1) + CLEAR_REG(q2) + CLEAR_REG(q3) + CLEAR_REG(q8) + CLEAR_REG(q9) + CLEAR_REG(q10) + CLEAR_REG(q11) + CLEAR_REG(q12) + CLEAR_REG(q13) + CLEAR_REG(q14) + +.Lxts_dec_skip: + pop {r4-r12,lr} + vpop {q4-q7} + bx lr +.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce; + + /* * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b); */ diff --git a/cipher/rijndael-armv8-aarch64-ce.S b/cipher/rijndael-armv8-aarch64-ce.S index 708ef34..40097a7 100644 --- a/cipher/rijndael-armv8-aarch64-ce.S +++ b/cipher/rijndael-armv8-aarch64-ce.S @@ -1277,6 +1277,280 @@ _gcry_aes_ocb_auth_armv8_ce: /* + * void _gcry_aes_xts_enc_armv8_ce (const void *keysched, + * unsigned char *outbuf, + * const unsigned char *inbuf, + * unsigned char *tweak, unsigned int nrounds); + */ + +.align 3 +.globl _gcry_aes_xts_enc_armv8_ce +.type _gcry_aes_xts_enc_armv8_ce,%function; +_gcry_aes_xts_enc_armv8_ce: + /* input: + * r0: keysched + * r1: outbuf + * r2: inbuf + * r3: tweak + * x4: nblocks + * w5: nrounds + */ + + cbz x4, .Lxts_enc_skip + + /* load tweak */ + ld1 {v0.16b}, [x3] + + /* load gfmul mask */ + mov x6, #0x87 + mov x7, #0x01 + mov v16.D[0], x6 + mov v16.D[1], x7 + + aes_preload_keys(x0, w5); + + b.eq .Lxts_enc_entry_192 + b.hi .Lxts_enc_entry_256 + +#define XTS_ENC(bits) \ + .Lxts_enc_entry_##bits: \ + cmp x4, #4; \ + b.lo .Lxts_enc_loop_##bits; \ + \ + .Lxts_enc_loop4_##bits: \ + \ + ext v4.16b, v0.16b, v0.16b, #8; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v5.2d, v0.2d, v0.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v5.16b, v5.16b, v2.16b; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v6.2d, v5.2d, v5.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v6.16b, v6.16b, v2.16b; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v7.2d, v6.2d, v6.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v7.16b, v7.16b, v2.16b; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v3.2d, v7.2d, v7.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v3.16b, v3.16b, v2.16b; \ + ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \ + st1 {v3.16b}, [x3]; \ + sub x4, x4, #4; \ + eor v1.16b, v1.16b, v0.16b; \ + \ + ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \ + cmp x4, #4; \ + eor v2.16b, v2.16b, v5.16b; \ + eor v3.16b, v3.16b, v6.16b; \ + eor v4.16b, v4.16b, v7.16b; \ + \ + do_aes_4_##bits(e, mc, v1, v2, v3, v4); \ + \ + eor v1.16b, v1.16b, v0.16b; \ + ld1 {v0.16b}, [x3]; \ + eor v2.16b, v2.16b, v5.16b; \ + eor v3.16b, v3.16b, v6.16b; \ + eor v4.16b, v4.16b, v7.16b; \ + st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \ + \ + b.hs .Lxts_enc_loop4_##bits; \ + CLEAR_REG(v3); \ + CLEAR_REG(v4); \ + CLEAR_REG(v5); \ + CLEAR_REG(v6); \ + CLEAR_REG(v7); \ + cbz x4, .Lxts_enc_done; \ + \ + .Lxts_enc_loop_##bits: \ + \ + ld1 {v1.16b}, [x2], #16; /* load plaintext */ \ + ext v3.16b, v0.16b, v0.16b, #8; \ + mov v2.16b, v0.16b; \ + sshr v3.2d, v3.2d, #63; \ + add v0.2d, v0.2d, v0.2d; \ + and v3.16b, v3.16b, v16.16b; \ + eor v1.16b, v1.16b, v2.16b; \ + eor v0.16b, v0.16b, v3.16b; \ + sub x4, x4, #1; \ + \ + do_aes_one##bits(e, mc, v1, v1); \ + \ + eor v1.16b, v1.16b, v2.16b; \ + st1 {v1.16b}, [x1], #16; /* store ciphertext */ \ + \ + cbnz x4, .Lxts_enc_loop_##bits; \ + b .Lxts_enc_done; + + XTS_ENC(128) + XTS_ENC(192) + XTS_ENC(256) + +#undef XTS_ENC + +.Lxts_enc_done: + aes_clear_keys(w5) + + st1 {v0.16b}, [x3] /* store tweak */ + + CLEAR_REG(v0) + CLEAR_REG(v1) + CLEAR_REG(v2) + +.Lxts_enc_skip: + ret + +.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce; + + +/* + * void _gcry_aes_xts_dec_armv8_ce (const void *keysched, + * unsigned char *outbuf, + * const unsigned char *inbuf, + * unsigned char *tweak, unsigned int nrounds); + */ + +.align 3 +.globl _gcry_aes_xts_dec_armv8_ce +.type _gcry_aes_xts_dec_armv8_ce,%function; +_gcry_aes_xts_dec_armv8_ce: + /* input: + * r0: keysched + * r1: outbuf + * r2: inbuf + * r3: tweak + * x4: nblocks + * w5: nrounds + */ + + cbz x4, .Lxts_dec_skip + + /* load tweak */ + ld1 {v0.16b}, [x3] + + /* load gfmul mask */ + mov x6, #0x87 + mov x7, #0x01 + mov v16.D[0], x6 + mov v16.D[1], x7 + + aes_preload_keys(x0, w5); + + b.eq .Lxts_dec_entry_192 + b.hi .Lxts_dec_entry_256 + +#define XTS_DEC(bits) \ + .Lxts_dec_entry_##bits: \ + cmp x4, #4; \ + b.lo .Lxts_dec_loop_##bits; \ + \ + .Lxts_dec_loop4_##bits: \ + \ + ext v4.16b, v0.16b, v0.16b, #8; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v5.2d, v0.2d, v0.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v5.16b, v5.16b, v2.16b; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v6.2d, v5.2d, v5.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v6.16b, v6.16b, v2.16b; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v7.2d, v6.2d, v6.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v7.16b, v7.16b, v2.16b; \ + \ + sshr v2.2d, v4.2d, #63; \ + add v3.2d, v7.2d, v7.2d; \ + and v2.16b, v2.16b, v16.16b; \ + add v4.2d, v4.2d, v4.2d; \ + eor v3.16b, v3.16b, v2.16b; \ + ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \ + st1 {v3.16b}, [x3]; \ + sub x4, x4, #4; \ + eor v1.16b, v1.16b, v0.16b; \ + \ + ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \ + cmp x4, #4; \ + eor v2.16b, v2.16b, v5.16b; \ + eor v3.16b, v3.16b, v6.16b; \ + eor v4.16b, v4.16b, v7.16b; \ + \ + do_aes_4_##bits(d, imc, v1, v2, v3, v4); \ + \ + eor v1.16b, v1.16b, v0.16b; \ + ld1 {v0.16b}, [x3]; \ + eor v2.16b, v2.16b, v5.16b; \ + eor v3.16b, v3.16b, v6.16b; \ + eor v4.16b, v4.16b, v7.16b; \ + st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \ + \ + b.hs .Lxts_dec_loop4_##bits; \ + CLEAR_REG(v3); \ + CLEAR_REG(v4); \ + CLEAR_REG(v5); \ + CLEAR_REG(v6); \ + CLEAR_REG(v7); \ + cbz x4, .Lxts_dec_done; \ + \ + .Lxts_dec_loop_##bits: \ + \ + ld1 {v1.16b}, [x2], #16; /* load plaintext */ \ + ext v3.16b, v0.16b, v0.16b, #8; \ + mov v2.16b, v0.16b; \ + sshr v3.2d, v3.2d, #63; \ + add v0.2d, v0.2d, v0.2d; \ + and v3.16b, v3.16b, v16.16b; \ + eor v1.16b, v1.16b, v2.16b; \ + eor v0.16b, v0.16b, v3.16b; \ + sub x4, x4, #1; \ + \ + do_aes_one##bits(d, imc, v1, v1); \ + \ + eor v1.16b, v1.16b, v2.16b; \ + st1 {v1.16b}, [x1], #16; /* store ciphertext */ \ + \ + cbnz x4, .Lxts_dec_loop_##bits; \ + b .Lxts_dec_done; + + XTS_DEC(128) + XTS_DEC(192) + XTS_DEC(256) + +#undef XTS_DEC + +.Lxts_dec_done: + aes_clear_keys(w5) + + st1 {v0.16b}, [x3] /* store tweak */ + + CLEAR_REG(v0) + CLEAR_REG(v1) + CLEAR_REG(v2) + +.Lxts_dec_skip: + ret + +.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce; + + +/* * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b); */ .align 3 diff --git a/cipher/rijndael-armv8-ce.c b/cipher/rijndael-armv8-ce.c index 334cf68..6af7108 100644 --- a/cipher/rijndael-armv8-ce.c +++ b/cipher/rijndael-armv8-ce.c @@ -101,6 +101,16 @@ extern void _gcry_aes_ocb_auth_armv8_ce (const void *keysched, size_t nblocks, unsigned int nrounds, unsigned int blkn); +extern void _gcry_aes_xts_enc_armv8_ce (const void *keysched, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *tweak, + size_t nblocks, unsigned int nrounds); +extern void _gcry_aes_xts_dec_armv8_ce (const void *keysched, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *tweak, + size_t nblocks, unsigned int nrounds); typedef void (*ocb_crypt_fn_t) (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, @@ -108,6 +118,11 @@ typedef void (*ocb_crypt_fn_t) (const void *keysched, unsigned char *outbuf, unsigned char *L_table, size_t nblocks, unsigned int nrounds, unsigned int blkn); +typedef void (*xts_crypt_fn_t) (const void *keysched, unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *tweak, size_t nblocks, + unsigned int nrounds); + void _gcry_aes_armv8_ce_setkey (RIJNDAEL_context *ctx, const byte *key) { @@ -361,4 +376,17 @@ _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, void *abuf_arg, nblocks, nrounds, (unsigned int)blkn); } +void +_gcry_aes_armv8_ce_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, + unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks, int encrypt) +{ + const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; + xts_crypt_fn_t crypt_fn = encrypt ? _gcry_aes_xts_enc_armv8_ce + : _gcry_aes_xts_dec_armv8_ce; + unsigned int nrounds = ctx->rounds; + + crypt_fn(keysched, outbuf, inbuf, tweak, nblocks, nrounds); +} + #endif /* USE_ARM_CE */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index df1363f..0f676fe 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -211,6 +211,11 @@ extern void _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, int encrypt); extern void _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); +extern void _gcry_aes_armv8_ce_xts_crypt (RIJNDAEL_context *ctx, + unsigned char *tweak, + unsigned char *outbuf, + const unsigned char *inbuf, + size_t nblocks, int encrypt); #endif /*USE_ARM_ASM*/ static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, @@ -1473,6 +1478,13 @@ _gcry_aes_xts_crypt (void *context, unsigned char *tweak, burn_depth = 0; } #endif /*USE_AESNI*/ +#ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { + _gcry_aes_armv8_ce_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); + burn_depth = 0; + } +#endif /*USE_ARM_CE*/ else { tweak_next_lo = buf_get_le64 (tweak + 0); ----------------------------------------------------------------------- Summary of changes: cipher/rijndael-armv8-aarch32-ce.S | 311 +++++++++++++++++++++++++++++++++++++ cipher/rijndael-armv8-aarch64-ce.S | 274 ++++++++++++++++++++++++++++++++ cipher/rijndael-armv8-ce.c | 28 ++++ cipher/rijndael.c | 12 ++ 4 files changed, 625 insertions(+) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jan 21 16:37:37 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 21 Jan 2018 16:37:37 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.3-117-g3f4ca85 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3f4ca85cb0cf58006417f4f7faafaa9a1f1bdf22 (commit) from 81d71818d054a5faa9153fd52a4b79bbbb71e9d5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3f4ca85cb0cf58006417f4f7faafaa9a1f1bdf22 Author: Werner Koch Date: Sun Jan 21 16:24:43 2018 +0100 gpg: First take on PKT_ENCRYPTED_AEAD. * common/openpgpdefs.h (PKT_ENCRYPTED_AEAD): New const. * g10/dek.h (DEK): Increase size of use_aead to 4 bits. * g10/filter.h (cipher_filter_context_t): Add new fields for AEAD. * g10/packet.h (PKT_encrypted): Add fields aead_algo, cipher_algo, and chunkbyte. * g10/build-packet.c (do_encrypted_aead): New. (build_packet): Call it. * g10/parse-packet.c (dump_sig_subpkt): Handle SIGSUBPKT_PREF_AEAD. (parse_one_sig_subpkt, can_handle_critical): Ditto. (parse_encrypted): Clear new PKT_ENCRYPTED fields. (parse_encrypted_aead): New. (parse): Call it. * g10/gpg.c (main): Take care of --rfc4880bis option when checking compliance. * g10/cipher-aead.c: Replace the stub by real code. * g10/decrypt-data.c (decode_filter_ctx_t): Add fields for use with AEAD. (aead_set_nonce): New. (aead_set_ad): New. (decrypt_data): Support AEAD. (aead_underflow): New. (aead_decode_filter): New. * g10/encrypt.c (use_aead): Make that new fucntion work. (encrypt_simple): Use default_aead_algo() instead of EAX. * g10/mainproc.c (proc_encrypted): Support AEAD. (do_proc_packets): Support PKT_ENCRYPTED_AEAD. -- This code has seen only a very few manual tests. Encrypting always uses a 64k chunks and decryption has not been tested with larger chunks. Those small chunks make debugging much faster. Tests can be done using: gpg --rfc4880bis --pinentry-mode=loopback --passphrase abc \ --force-aead --aead-algo ocb --s2k-mode 0 --cipher AES \ -v -z 0 --status-fd 2 -c OUTFILE and gpg --rfc4880bis --pinentry-mode=loopback --passphrase=abc \ --status-fd 2 -v -d OUTFILE Signed-off-by: Werner Koch diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index aeb3389..8699a17 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -51,6 +51,7 @@ typedef enum PKT_ATTRIBUTE = 17, /* PGP's attribute packet. */ PKT_ENCRYPTED_MDC = 18, /* Integrity protected encrypted data. */ PKT_MDC = 19, /* Manipulation detection code packet. */ + PKT_ENCRYPTED_AEAD= 20, /* AEAD encrypted data packet. */ PKT_COMMENT = 61, /* new comment packet (GnuPG specific). */ PKT_GPG_CONTROL = 63 /* internal control packet (GnuPG specific). */ } @@ -143,6 +144,7 @@ typedef enum cipher_algo_t; +/* Note that we encode the AEAD algo in a 3 bit field at some places. */ typedef enum { AEAD_ALGO_NONE = 0, diff --git a/doc/DETAILS b/doc/DETAILS index 3c089b2..a4063b4 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -518,9 +518,10 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: actual key used for descryption. is the fingerprint of the primary key. is the letter with the ownertrust; this is in general a 'u' which stands for ultimately trusted. -*** DECRYPTION_INFO +*** DECRYPTION_INFO [] Print information about the symmetric encryption algorithm and the MDC method. This will be emitted even if the decryption fails. + For an AEAD algorithm AEAD_ALGO is not 0. *** DECRYPTION_FAILED The symmetric decryption failed - one reason could be a wrong @@ -540,8 +541,10 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: --override-session-key. It is not an indication that the decryption will or has succeeded. -*** BEGIN_ENCRYPTION +*** BEGIN_ENCRYPTION [] Mark the start of the actual encryption process. + MDC_METHOD shall be 0 if an AEAD_ALGO is not 0. Users should + however ignore MDC_METHOD if AEAD_ALGO is not 0. *** END_ENCRYPTION Mark the end of the actual encryption process. diff --git a/g10/build-packet.c b/g10/build-packet.c index d4a1d6a..fc64c9c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -42,6 +42,7 @@ static u32 calc_plaintext( PKT_plaintext *pt ); static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ); static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed ); static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ); +static int do_encrypted_aead (iobuf_t out, int ctb, PKT_encrypted *ed); static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd ); static int do_signature( IOBUF out, int ctb, PKT_signature *sig ); static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops ); @@ -106,6 +107,7 @@ build_packet (IOBUF out, PACKET *pkt) break; case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: + case PKT_ENCRYPTED_AEAD: new_ctb = pkt->pkt.encrypted->new_ctb; break; case PKT_COMPRESSED: @@ -158,6 +160,9 @@ build_packet (IOBUF out, PACKET *pkt) case PKT_ENCRYPTED_MDC: rc = do_encrypted_mdc (out, ctb, pkt->pkt.encrypted); break; + case PKT_ENCRYPTED_AEAD: + rc = do_encrypted_aead (out, ctb, pkt->pkt.encrypted); + break; case PKT_COMPRESSED: rc = do_compressed (out, ctb, pkt->pkt.compressed); break; @@ -812,6 +817,32 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ) } +/* Serialize the symmetrically AEAD encrypted data packet + * (rfc4880bis-03, Section 5.16) described by ED and write it to OUT. + * + * Note: this only writes only packet's header. The caller must then + * follow up and write the actual encrypted data. This should be done + * by pushing the the cipher_filter_aead. */ +static int +do_encrypted_aead (iobuf_t out, int ctb, PKT_encrypted *ed) +{ + u32 n; + + log_assert (ctb_pkttype (ctb) == PKT_ENCRYPTED_AEAD); + + n = ed->len ? (ed->len + ed->extralen + 4) : 0; + write_header (out, ctb, n ); + iobuf_writebyte (out, 1); /* Version. */ + iobuf_writebyte (out, ed->cipher_algo); + iobuf_writebyte (out, ed->aead_algo); + iobuf_writebyte (out, ed->chunkbyte); + + /* This is all. The caller has to write the encrypted data */ + + return 0; +} + + /* Serialize the compressed packet (RFC 4880, Section 5.6) described by CD and write it to OUT. diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index bf0afcf..f247a83 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -33,13 +33,392 @@ #include "options.h" #include "main.h" +/* The size of the buffer we allocate to encrypt the data. This must + * be a multiple of the OCB blocksize (16 byte). */ +#define AEAD_ENC_BUFFER_SIZE (64*1024) + + +/* Wrapper around iobuf_write to make sure that a proper error code is + * always returned. */ +static gpg_error_t +my_iobuf_write (iobuf_t a, const void *buffer, size_t buflen) +{ + if (iobuf_write (a, buffer, buflen)) + { + gpg_error_t err = iobuf_error (a); + if (!err || !gpg_err_code (err)) /* (The latter should never happen) */ + err = gpg_error (GPG_ERR_EIO); + return err; + } + return 0; +} + + +/* Set the additional data for the current chunk. If FINAL is set the + * final AEAD chunk is processed. */ +static gpg_error_t +set_additional_data (cipher_filter_context_t *cfx, int final) +{ + unsigned char ad[21]; + + ad[0] = (0xc0 | PKT_ENCRYPTED_AEAD); + ad[1] = 1; + ad[2] = cfx->dek->algo; + ad[3] = cfx->dek->use_aead; + ad[4] = cfx->chunkbyte; + ad[5] = cfx->chunkindex >> 56; + ad[6] = cfx->chunkindex >> 48; + ad[7] = cfx->chunkindex >> 40; + ad[8] = cfx->chunkindex >> 32; + ad[9] = cfx->chunkindex >> 24; + ad[10]= cfx->chunkindex >> 16; + ad[11]= cfx->chunkindex >> 8; + ad[12]= cfx->chunkindex; + if (final) + { + ad[13] = cfx->total >> 56; + ad[14] = cfx->total >> 48; + ad[15] = cfx->total >> 40; + ad[16] = cfx->total >> 32; + ad[17] = cfx->total >> 24; + ad[18] = cfx->total >> 16; + ad[19] = cfx->total >> 8; + ad[20] = cfx->total; + } + log_printhex (ad, final? 21 : 13, "authdata:"); + return gcry_cipher_authenticate (cfx->cipher_hd, ad, final? 21 : 13); +} + + +/* Set the nonce. This also reset the encryption machinery so that + * the handle can be used for a new chunk. */ +static gpg_error_t +set_nonce (cipher_filter_context_t *cfx) +{ + unsigned char nonce[16]; + int i; + + switch (cfx->dek->use_aead) + { + case AEAD_ALGO_OCB: + memcpy (nonce, cfx->startiv, 15); + i = 7; + break; + + case AEAD_ALGO_EAX: + memcpy (nonce, cfx->startiv, 16); + i = 8; + break; + + default: + BUG (); + } + + nonce[i++] ^= cfx->chunkindex >> 56; + nonce[i++] ^= cfx->chunkindex >> 48; + nonce[i++] ^= cfx->chunkindex >> 40; + nonce[i++] ^= cfx->chunkindex >> 32; + nonce[i++] ^= cfx->chunkindex >> 24; + nonce[i++] ^= cfx->chunkindex >> 16; + nonce[i++] ^= cfx->chunkindex >> 8; + nonce[i++] ^= cfx->chunkindex; + + log_printhex (nonce, 15, "nonce:"); + return gcry_cipher_setiv (cfx->cipher_hd, nonce, i); +} + + +static gpg_error_t +write_header (cipher_filter_context_t *cfx, iobuf_t a) +{ + gpg_error_t err; + PACKET pkt; + PKT_encrypted ed; + unsigned int blocksize; + unsigned int startivlen; + enum gcry_cipher_modes ciphermode; + + log_assert (cfx->dek->use_aead); + + blocksize = openpgp_cipher_get_algo_blklen (cfx->dek->algo); + if (blocksize != 16 ) + log_fatal ("unsupported blocksize %u for AEAD\n", blocksize); + + switch (cfx->dek->use_aead) + { + case AEAD_ALGO_OCB: + ciphermode = GCRY_CIPHER_MODE_OCB; + startivlen = 15; + break; + + default: + log_error ("unsupported AEAD algo %d\n", cfx->dek->use_aead); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } + + cfx->chunkbyte = 10; + cfx->chunksize = (uint64_t)1 << (cfx->chunkbyte + 6); + cfx->chunklen = 0; + cfx->bufsize = AEAD_ENC_BUFFER_SIZE; + cfx->buflen = 0; + cfx->buffer = xtrymalloc (cfx->bufsize); + if (!cfx->buffer) + return gpg_error_from_syserror (); + + memset (&ed, 0, sizeof ed); + ed.new_ctb = 1; /* (Is anyway required for the packet type). */ + ed.len = 0; /* fixme: cfx->datalen */ + ed.extralen = startivlen + 16; /* (16 is the taglen) */ + ed.cipher_algo = cfx->dek->algo; + ed.aead_algo = cfx->dek->use_aead; + ed.chunkbyte = cfx->chunkbyte; + + init_packet (&pkt); + pkt.pkttype = PKT_ENCRYPTED_AEAD; + pkt.pkt.encrypted = &ed; + + log_debug ("aead packet: len=%lu extralen=%d\n", + (unsigned long)ed.len, ed.extralen); + + write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", + cfx->dek->algo, ed.aead_algo); + print_cipher_algo_note (cfx->dek->algo); + + if (build_packet( a, &pkt)) + log_bug ("build_packet(ENCRYPTED_AEAD) failed\n"); + + log_assert (sizeof cfx->startiv >= startivlen); + gcry_randomize (cfx->startiv, startivlen, GCRY_STRONG_RANDOM); + err = my_iobuf_write (a, cfx->startiv, startivlen); + if (err) + goto leave; + + err = openpgp_cipher_open (&cfx->cipher_hd, + cfx->dek->algo, + ciphermode, + GCRY_CIPHER_SECURE); + if (err) + goto leave; + + log_printhex (cfx->dek->key, cfx->dek->keylen, "thekey:"); + err = gcry_cipher_setkey (cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen); + if (err) + return err; + + err = set_nonce (cfx); + if (err) + return err; + + err = set_additional_data (cfx, 0); + if (err) + return err; + + cfx->wrote_header = 1; + + leave: + return err; +} + + +/* Get and write the auth tag to stream A. */ +static gpg_error_t +write_auth_tag (cipher_filter_context_t *cfx, iobuf_t a) +{ + gpg_error_t err; + char tag[16]; + + err = gcry_cipher_gettag (cfx->cipher_hd, tag, 16); + if (err) + goto leave; + err = my_iobuf_write (a, tag, 16); + if (err) + goto leave; + log_printhex (tag, 16, "wrote tag:"); + + leave: + return err; +} + + +/* Write the final chunk to stream A. */ +static gpg_error_t +write_final_chunk (cipher_filter_context_t *cfx, iobuf_t a) +{ + gpg_error_t err; + char dummy[1]; + + cfx->chunkindex++; + + err = set_nonce (cfx); + if (err) + goto leave; + err = set_additional_data (cfx, 1); + if (err) + goto leave; + + gcry_cipher_final (cfx->cipher_hd); + + /* Encrypt an empty string. */ + err = gcry_cipher_encrypt (cfx->cipher_hd, dummy, 0, NULL, 0); + if (err) + goto leave; + + err = write_auth_tag (cfx, a); + + leave: + return err; +} + + +/* The core of the flush sub-function of cipher_filter_aead. */ +static gpg_error_t +do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) +{ + gpg_error_t err; + int newchunk = 0; + size_t n; + + /* Put the data into a buffer, flush and encrypt as needed. */ + log_debug ("flushing %zu bytes (cur buflen=%zu)\n", size, cfx->buflen); + do + { + if (cfx->buflen + size < cfx->bufsize) + n = size; + else + n = cfx->bufsize - cfx->buflen; + + if (cfx->chunklen + n >= cfx->chunksize) + { + size_t n1 = cfx->chunksize - cfx->chunklen; + newchunk = 1; + log_debug ("chunksize %ju reached;" + " cur buflen=%zu using %zu of %zu\n", + (uintmax_t)cfx->chunksize, (uintmax_t)cfx->buflen, + n1, n); + n = n1; + } + + memcpy (cfx->buffer + cfx->buflen, buf, n); + cfx->buflen += n; + buf += n; + size -= n; + + if (cfx->buflen == cfx->bufsize || newchunk) + { + log_debug ("encrypting: buflen=%zu %s %p\n", + cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd); + if (newchunk) + gcry_cipher_final (cfx->cipher_hd); + if (newchunk) + log_printhex (cfx->buffer, cfx->buflen, "plain(1):"); + else if (cfx->buflen > 32) + log_printhex (cfx->buffer + cfx->buflen - 32, 32, + "plain(last 32):"); + + /* Take care: even with a buflen of zero an encrypt needs to + * be called after gcry_cipher_final and before + * gcry_cipher_gettag - at least with libgcrypt 1.8 and OCB + * mode. */ + gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, + NULL, 0); + if (newchunk) + log_printhex (cfx->buffer, cfx->buflen, "ciphr(1):"); + err = my_iobuf_write (a, cfx->buffer, cfx->buflen); + if (err) + goto leave; + cfx->chunklen += cfx->buflen; + cfx->total += cfx->buflen; + cfx->buflen = 0; + + if (newchunk) + { + log_debug ("chunklen=%ju total=%ju\n", + (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total); + err = write_auth_tag (cfx, a); + if (err) + { + log_debug ("gcry_cipher_gettag failed: %s\n", + gpg_strerror (err)); + goto leave; + } + + log_debug ("starting a new chunk (cur size=%zu)\n", size); + log_printhex (buf, size, "cur buf:"); + cfx->chunkindex++; + cfx->chunklen = 0; + err = set_nonce (cfx); + if (err) + goto leave; + err = set_additional_data (cfx, 0); + if (err) + goto leave; + newchunk = 0; + } + } + } + while (size); + + leave: + return err; +} + + +/* The core of the free sub-function of cipher_filter_aead. */ +static gpg_error_t +do_free (cipher_filter_context_t *cfx, iobuf_t a) +{ + gpg_error_t err = 0; + + /* FIXME: Check what happens if we just wrote the last chunk and no + * more bytes were to encrypt. We should then not call finalize and + * write the auth tag again, right? May this at all happen? */ + + /* Call finalize which will also allow us to flush out and encrypt + * the last arbitrary length buffer. */ + gcry_cipher_final (cfx->cipher_hd); + + /* Encrypt any remaining bytes. */ + if (cfx->buflen) + { + log_debug ("processing last %zu bytes of the last chunk\n", cfx->buflen); + log_printhex (cfx->buffer, cfx->buflen, "plain(2):"); + gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, NULL, 0); + log_printhex (cfx->buffer, cfx->buflen, "ciphr(2):"); + err = my_iobuf_write (a, cfx->buffer, cfx->buflen); + if (err) + goto leave; + /* log_printhex (cfx->buffer, cfx->buflen, "wrote:"); */ + cfx->chunklen += cfx->buflen; + cfx->total += cfx->buflen; + } + + /* Get and write the authentication tag. */ + log_debug ("chunklen=%ju total=%ju\n", + (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total); + err = write_auth_tag (cfx, a); + if (err) + goto leave; + + /* Write the final chunk. */ + log_debug ("creating final chunk\n"); + err = write_final_chunk (cfx, a); + + leave: + xfree (cfx->buffer); + cfx->buffer = NULL; + /* gcry_cipher_close (cfx->cipher_hd); */ + /* cfx->cipher_hd = NULL; */ + return err; +} + /* - * This filter is used to encipher data with an AEAD algorithm + * This filter is used to encrypt data with an AEAD algorithm */ int cipher_filter_aead (void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) + iobuf_t a, byte *buf, size_t *ret_len) { cipher_filter_context_t *cfx = opaque; size_t size = *ret_len; @@ -47,16 +426,18 @@ cipher_filter_aead (void *opaque, int control, if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */ { - rc = -1; /* not yet used */ + rc = -1; /* not used */ } else if (control == IOBUFCTRL_FLUSH) /* encrypt */ { - log_assert (a); - rc = GPG_ERR_NOT_IMPLEMENTED; + if (!cfx->wrote_header && (rc=write_header (cfx, a))) + ; + else + rc = do_flush (cfx, a, buf, size); } else if (control == IOBUFCTRL_FREE) { - gcry_cipher_close (cfx->cipher_hd); + rc = do_free (cfx, a); } else if (control == IOBUFCTRL_DESC) { diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 736534d..80e16ec 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -1,6 +1,6 @@ /* decrypt-data.c - Decrypt an encrypted data packet - * Copyright (C) 1998, 1999, 2000, 2001, 2005, - * 2006, 2009 Free Software Foundation, Inc. + * Copyright (C) 1998-2001, 2005-2006, 2009 Free Software Foundation, Inc. + * Copyright (C) 1998-2001, 2005-2006, 2009, 2018 Werner Koch * * This file is part of GnuPG. * @@ -32,22 +32,71 @@ #include "../common/compliance.h" +static int aead_decode_filter (void *opaque, int control, iobuf_t a, + byte *buf, size_t *ret_len); static int mdc_decode_filter ( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len); static int decode_filter ( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len); -typedef struct decode_filter_context_s +/* Our context object. */ +struct decode_filter_context_s { + /* Recounter (max value is 2). We need it becuase we do not know + * whether the iobuf or the outer control code frees this object + * first. */ + int refcount; + + /* The cipher handle. */ gcry_cipher_hd_t cipher_hd; + + /* The hash handle for use in MDC mode. */ gcry_md_hd_t mdc_hash; - char defer[22]; - int defer_filled; - int eof_seen; - int refcount; - int partial; /* Working on a partial length packet. */ - size_t length; /* If !partial: Remaining bytes in the packet. */ -} *decode_filter_ctx_t; + + /* The start IV for AEAD encryption. */ + byte startiv[16]; + + /* The holdback buffer. For AEAD we need 32 bytes for MDC 22 bytes + * are enough. The flag indicates whether the holdback buffer is + * filled. */ + char defer[32]; + unsigned int defer_filled : 1; + + /* Working on a partial length packet. */ + unsigned int partial : 1; + + /* EOF indicator with these true values: + * 1 = normal EOF + * 2 = premature EOF (tag incomplete) + * 3 = premature EOF (general) */ + unsigned int eof_seen : 2; + + /* The actually used cipher algo for AEAD. */ + byte cipher_algo; + + /* The AEAD algo. */ + byte aead_algo; + + /* The encoded chunk byte for AEAD. */ + byte chunkbyte; + + /* The decoded CHUNKBYTE. */ + uint64_t chunksize; + + /* The chunk index for AEAD. */ + uint64_t chunkindex; + + /* The number of bytes in the current chunk. */ + uint64_t chunklen; + + /* The total count of decrypted plaintext octets. */ + uint64_t total; + + /* Remaining bytes in the packet according to the packet header. + * Not used if PARTIAL is true. */ + size_t length; +}; +typedef struct decode_filter_context_s *decode_filter_ctx_t; /* Helper to release the decode context. */ @@ -69,6 +118,78 @@ release_dfx_context (decode_filter_ctx_t dfx) } +/* Set the nonce for AEAD. This also reset the decryption machinery + * so that the handle can be used for a new chunk. */ +static gpg_error_t +aead_set_nonce (decode_filter_ctx_t dfx) +{ + unsigned char nonce[16]; + int i; + + switch (dfx->aead_algo) + { + case AEAD_ALGO_OCB: + memcpy (nonce, dfx->startiv, 15); + i = 7; + break; + + case AEAD_ALGO_EAX: + memcpy (nonce, dfx->startiv, 16); + i = 8; + break; + + default: + BUG (); + } + nonce[i++] ^= dfx->chunkindex >> 56; + nonce[i++] ^= dfx->chunkindex >> 48; + nonce[i++] ^= dfx->chunkindex >> 40; + nonce[i++] ^= dfx->chunkindex >> 32; + nonce[i++] ^= dfx->chunkindex >> 24; + nonce[i++] ^= dfx->chunkindex >> 16; + nonce[i++] ^= dfx->chunkindex >> 8; + nonce[i++] ^= dfx->chunkindex; + + log_printhex (nonce, i, "nonce:"); + return gcry_cipher_setiv (dfx->cipher_hd, nonce, i); +} + + +/* Set the additional data for the current chunk. If FINAL is set the + * final AEAD chunk is processed. */ +static gpg_error_t +aead_set_ad (decode_filter_ctx_t dfx, int final) +{ + unsigned char ad[21]; + + ad[0] = (0xc0 | PKT_ENCRYPTED_AEAD); + ad[1] = 1; + ad[2] = dfx->cipher_algo; + ad[3] = dfx->aead_algo; + ad[4] = dfx->chunkbyte; + ad[5] = dfx->chunkindex >> 56; + ad[6] = dfx->chunkindex >> 48; + ad[7] = dfx->chunkindex >> 40; + ad[8] = dfx->chunkindex >> 32; + ad[9] = dfx->chunkindex >> 24; + ad[10]= dfx->chunkindex >> 16; + ad[11]= dfx->chunkindex >> 8; + ad[12]= dfx->chunkindex; + if (final) + { + ad[13] = dfx->total >> 56; + ad[14] = dfx->total >> 48; + ad[15] = dfx->total >> 40; + ad[16] = dfx->total >> 32; + ad[17] = dfx->total >> 24; + ad[18] = dfx->total >> 16; + ad[19] = dfx->total >> 8; + ad[20] = dfx->total; + } + log_printhex (ad, final? 21 : 13, "authdata:"); + return gcry_cipher_authenticate (dfx->cipher_hd, ad, final? 21 : 13); +} + /**************** * Decrypt the data, specified by ED with the key DEK. @@ -80,8 +201,8 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) byte *p; int rc=0, c, i; byte temp[32]; - unsigned blocksize; - unsigned nprefix; + unsigned int blocksize; + unsigned int nprefix; dfx = xtrycalloc (1, sizeof *dfx); if (!dfx) @@ -109,19 +230,18 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) goto leave; } - { - char buf[20]; - - snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo); - write_status_text (STATUS_DECRYPTION_INFO, buf); - } + write_status_printf (STATUS_DECRYPTION_INFO, "%d %d %d", + ed->mdc_method, dek->algo, ed->aead_algo); if (opt.show_session_key) { - char numbuf[25]; + char numbuf[30]; char *hexbuf; - snprintf (numbuf, sizeof numbuf, "%d:", dek->algo); + if (ed->aead_algo) + snprintf (numbuf, sizeof numbuf, "%d.%u:", dek->algo, ed->aead_algo); + else + snprintf (numbuf, sizeof numbuf, "%d:", dek->algo); hexbuf = bin2hex (dek->key, dek->keylen, NULL); if (!hexbuf) { @@ -139,95 +259,209 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) blocksize = openpgp_cipher_get_algo_blklen (dek->algo); if ( !blocksize || blocksize > 16 ) log_fatal ("unsupported blocksize %u\n", blocksize ); - nprefix = blocksize; - if ( ed->len && ed->len < (nprefix+2) ) + if (ed->aead_algo) { - /* An invalid message. We can't check that during parsing - because we may not know the used cipher then. */ - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } + enum gcry_cipher_modes ciphermode; + unsigned int startivlen; - if ( ed->mdc_method ) - { - if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 )) - BUG (); - if ( DBG_HASHING ) - gcry_md_debug (dfx->mdc_hash, "checkmdc"); - } + if (blocksize != 16) + { + rc = gpg_error (GPG_ERR_CIPHER_ALGO); + goto leave; + } - rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo, - GCRY_CIPHER_MODE_CFB, - (GCRY_CIPHER_SECURE - | ((ed->mdc_method || dek->algo >= 100)? - 0 : GCRY_CIPHER_ENABLE_SYNC))); - if (rc) - { - /* We should never get an error here cause we already checked - * that the algorithm is available. */ - BUG(); - } + switch (ed->aead_algo) + { + case AEAD_ALGO_OCB: + startivlen = 15; + ciphermode = GCRY_CIPHER_MODE_OCB; + break; + case AEAD_ALGO_EAX: + startivlen = 16; + log_error ("unsupported AEAD algo %d\n", ed->aead_algo); + rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + default: + log_error ("unknown AEAD algo %d\n", ed->aead_algo); + rc = gpg_error (GPG_ERR_INV_CIPHER_MODE); + goto leave; + } + log_assert (startivlen <= sizeof dfx->startiv); + if (ed->chunkbyte != 10) + { + /* FIXME */ + log_error ("unsupported chunkbyte %u\n", ed->chunkbyte); + rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } - /* log_hexdump( "thekey", dek->key, dek->keylen );*/ - rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen); - if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) - { - log_info(_("WARNING: message was encrypted with" - " a weak key in the symmetric cipher.\n")); - rc=0; - } - else if( rc ) - { - log_error("key setup failed: %s\n", gpg_strerror (rc) ); - goto leave; - } + /* Read the Start-IV. */ + if (ed->len) + { + for (i=0; i < startivlen && ed->len; i++, ed->len--) + { + if ((c=iobuf_get (ed->buf)) == -1) + break; + dfx->startiv[i] = c; + } + } + else + { + for (i=0; i < startivlen; i++ ) + if ( (c=iobuf_get (ed->buf)) == -1 ) + break; + else + dfx->startiv[i] = c; + } + if (i != startivlen) + { + log_error ("Start-IV in AEAD packet too short (%d/%u)\n", + i, startivlen); + rc = gpg_error (GPG_ERR_TOO_SHORT); + goto leave; + } - if (!ed->buf) - { - log_error(_("problem handling encrypted packet\n")); - goto leave; - } + dfx->cipher_algo = ed->cipher_algo; + dfx->aead_algo = ed->aead_algo; + dfx->chunkbyte = ed->chunkbyte; + dfx->chunksize = (uint64_t)1 << (dfx->chunkbyte + 6); - gcry_cipher_setiv (dfx->cipher_hd, NULL, 0); + if (dek->algo != dfx->cipher_algo) + log_info ("Note: different cipher algorithms used (%s/%s)\n", + openpgp_cipher_algo_name (dek->algo), + openpgp_cipher_algo_name (dfx->cipher_algo)); - if ( ed->len ) - { - for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) + rc = openpgp_cipher_open (&dfx->cipher_hd, + dfx->cipher_algo, + ciphermode, + GCRY_CIPHER_SECURE); + if (rc) + goto leave; /* Should never happen. */ + + log_printhex (dek->key, dek->keylen, "thekey:"); + rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen); + if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY) { - if ( (c=iobuf_get(ed->buf)) == -1 ) - break; - else - temp[i] = c; + log_info (_("WARNING: message was encrypted with" + " a weak key in the symmetric cipher.\n")); + rc = 0; } + else if (rc) + { + log_error("key setup failed: %s\n", gpg_strerror (rc)); + goto leave; + } + + if (!ed->buf) + { + log_error(_("problem handling encrypted packet\n")); + goto leave; + } + + rc = aead_set_nonce (dfx); + if (rc) + goto leave; + + rc = aead_set_ad (dfx, 0); + if (rc) + goto leave; + } - else + else /* CFB encryption. */ { - for (i=0; i < (nprefix+2); i++ ) - if ( (c=iobuf_get(ed->buf)) == -1 ) - break; - else - temp[i] = c; - } + nprefix = blocksize; + if ( ed->len && ed->len < (nprefix+2) ) + { + /* An invalid message. We can't check that during parsing + because we may not know the used cipher then. */ + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + + if ( ed->mdc_method ) + { + if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 )) + BUG (); + if ( DBG_HASHING ) + gcry_md_debug (dfx->mdc_hash, "checkmdc"); + } + + rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo, + GCRY_CIPHER_MODE_CFB, + (GCRY_CIPHER_SECURE + | ((ed->mdc_method || dek->algo >= 100)? + 0 : GCRY_CIPHER_ENABLE_SYNC))); + if (rc) + { + /* We should never get an error here cause we already checked + * that the algorithm is available. */ + BUG(); + } - gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0); - gcry_cipher_sync (dfx->cipher_hd); - p = temp; - /* log_hexdump( "prefix", temp, nprefix+2 ); */ - if (dek->symmetric - && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) ) - { - rc = gpg_error (GPG_ERR_BAD_KEY); - goto leave; - } - if ( dfx->mdc_hash ) - gcry_md_write (dfx->mdc_hash, temp, nprefix+2); + /* log_hexdump( "thekey", dek->key, dek->keylen );*/ + rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen); + if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) + { + log_info(_("WARNING: message was encrypted with" + " a weak key in the symmetric cipher.\n")); + rc=0; + } + else if( rc ) + { + log_error("key setup failed: %s\n", gpg_strerror (rc) ); + goto leave; + } + + if (!ed->buf) + { + log_error(_("problem handling encrypted packet\n")); + goto leave; + } + + gcry_cipher_setiv (dfx->cipher_hd, NULL, 0); + + if ( ed->len ) + { + for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) + { + if ( (c=iobuf_get(ed->buf)) == -1 ) + break; + else + temp[i] = c; + } + } + else + { + for (i=0; i < (nprefix+2); i++ ) + if ( (c=iobuf_get(ed->buf)) == -1 ) + break; + else + temp[i] = c; + } + + gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0); + gcry_cipher_sync (dfx->cipher_hd); + p = temp; + /* log_hexdump( "prefix", temp, nprefix+2 ); */ + if (dek->symmetric + && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) ) + { + rc = gpg_error (GPG_ERR_BAD_KEY); + goto leave; + } + + if ( dfx->mdc_hash ) + gcry_md_write (dfx->mdc_hash, temp, nprefix+2); + } dfx->refcount++; - dfx->partial = ed->is_partial; + dfx->partial = !!ed->is_partial; dfx->length = ed->len; - if ( ed->mdc_method ) + if (ed->aead_algo) + iobuf_push_filter ( ed->buf, aead_decode_filter, dfx ); + else if (ed->mdc_method) iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx ); else iobuf_push_filter ( ed->buf, decode_filter, dfx ); @@ -307,6 +541,296 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) } +/* The core of the AEAD decryption. This is the underflow function of + * the aead_decode_filter. */ +static gpg_error_t +aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) +{ + const size_t size = *ret_len; /* The initial length of BUF. */ + gpg_error_t err; + size_t n; /* Finally the number of decrypted bytes in BUF. */ + int c; + + log_assert (size > 64); /* Our code requires at least this size. */ + + /* Get at least 32 bytes and put it ahead in the buffer. */ + if (dfx->partial) + { + for (n=32; n < 64; n++) + { + if ((c = iobuf_get (a)) == -1) + break; + buf[n] = c; + } + } + else + { + for (n=32; n < 64 && dfx->length; n++, dfx->length--) + { + if ((c = iobuf_get (a)) == -1) + break; /* Premature EOF. */ + buf[n] = c; + } + } + + if (n == 64) + { + /* We got 32 bytes from A which are good for the last chunk's + * auth tag and the final chunk's auth tag. On the first time + * we don't have anything in the defer buffer and thus we move + * those 32 bytes to the start of the buffer. All further calls + * will copy the deferred 32 bytes to the start of the + * buffer. */ + if (!dfx->defer_filled) + { + memcpy (buf, buf+32, 32); + n = 32; /* Continue at this position. */ + } + else + { + memcpy (buf, dfx->defer, 32); + } + + /* Now fill up the provided buffer. */ + if (dfx->partial) + { + for (; n < size; n++ ) + { + if ((c = iobuf_get (a)) == -1) + { + dfx->eof_seen = 1; /* Normal EOF. */ + break; + } + buf[n] = c; + } + } + else + { + for (; n < size && dfx->length; n++, dfx->length--) + { + c = iobuf_get (a); + if (c == -1) + { + dfx->eof_seen = 3; /* Premature EOF. */ + break; + } + buf[n] = c; + } + if (!dfx->length) + dfx->eof_seen = 1; /* Normal EOF. */ + } + + /* Move the trailing 32 bytes back to the defer buffer. We + * got at least 64 bytes and thus a memmove is not needed. */ + n -= 32; + memcpy (dfx->defer, buf+n, 32); + dfx->defer_filled = 1; + } + else if (!dfx->defer_filled) + { + /* EOF seen but empty defer buffer. This means that we did not + * read enough for the two auth tags. */ + n -= 32; + memcpy (buf, buf+32, n ); + dfx->eof_seen = 2; /* EOF with incomplete tag. */ + } + else + { + /* EOF seen (i.e. read less than 32 bytes). */ + memcpy (buf, dfx->defer, 32); + n -= 32; + memcpy (dfx->defer, buf+n, 32); + dfx->eof_seen = 1; /* Normal EOF. */ + } + + log_debug ("decrypt: chunklen=%ju total=%ju size=%zu n=%zu%s\n", + (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, size, n, + dfx->eof_seen? " eof":""); + + /* Now decrypt the buffer. */ + if (n && dfx->eof_seen > 1) + { + err = gpg_error (GPG_ERR_TRUNCATED); + } + else if (!n) + { + log_assert (dfx->eof_seen); + err = gpg_error (GPG_ERR_EOF); + } + else + { + size_t off = 0; + + if (dfx->chunklen + n >= dfx->chunksize) + { + size_t n0 = dfx->chunksize - dfx->chunklen; + + log_debug ("chunksize will be reached: n0=%zu\n", n0); + gcry_cipher_final (dfx->cipher_hd); + err = gcry_cipher_decrypt (dfx->cipher_hd, buf, n0, NULL, 0); + if (err) + { + log_debug ("gcry_cipher_decrypt failed (1): %s\n", + gpg_strerror (err)); + goto leave; + } + /*log_printhex (buf, n, "buf:");*/ + dfx->chunklen += n0; + dfx->total += n0; + off = n0; + n -= n0; + + log_debug ("bytes left: %zu off=%zu\n", n, off); + log_assert (n >= 16); + log_assert (dfx->defer_filled); + log_printhex (buf+off, 16, "tag:"); + err = gcry_cipher_checktag (dfx->cipher_hd, buf + off, 16); + if (err) + { + log_debug ("gcry_cipher_checktag failed (1): %s\n", + gpg_strerror (err)); + /* Return Bad Signature like we do with MDC encryption. */ + if (gpg_err_code (err) == GPG_ERR_CHECKSUM) + err = gpg_error (GPG_ERR_BAD_SIGNATURE); + goto leave; + } + /* Remove that tag from the output. */ + memmove (buf + off, buf + off + 16, n - 16); + n -= 16; + + /* Prepare a new chunk. */ + dfx->chunklen = 0; + dfx->chunkindex++; + err = aead_set_nonce (dfx); + if (err) + goto leave; + err = aead_set_ad (dfx, 0); + if (err) + goto leave; + } + + if (dfx->eof_seen) + { + /* This is the last block of the last chunk. Its length may + * not be a multiple of the block length. We expect that it + * is followed by two authtags. The first being the one + * from the current chunk and the second form the final + * chunk encrypting the empty string. Note that for the + * other blocks we assume a multiple of the block length + * which is only true because the filter is called with + * large 2^n sized buffers. There is no assert because + * gcry_cipher_decrypt would detect such an error. */ + gcry_cipher_final (dfx->cipher_hd); + /*log_printhex (buf+off, n, "buf+off:");*/ + } + err = gcry_cipher_decrypt (dfx->cipher_hd, buf + off, n, NULL, 0); + if (err) + { + log_debug ("gcry_cipher_decrypt failed (2): %s\n",gpg_strerror (err)); + goto leave; + } + dfx->chunklen += n; + dfx->total += n; + + if (dfx->eof_seen) + { + /* log_printhex (buf+off, n, "buf+off:"); */ + log_debug ("eof seen: chunklen=%ju total=%ju off=%zu n=%zu\n", + (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, off, n); + + log_assert (dfx->defer_filled); + err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer, 16); + if (err) + { + log_debug ("gcry_cipher_checktag failed (2): %s\n", + gpg_strerror (err)); + /* Return Bad Signature like we do with MDC encryption. */ + if (gpg_err_code (err) == GPG_ERR_CHECKSUM) + err = gpg_error (GPG_ERR_BAD_SIGNATURE); + goto leave; + } + + /* Check the final chunk. */ + dfx->chunkindex++; + err = aead_set_nonce (dfx); + if (err) + goto leave; + err = aead_set_ad (dfx, 1); + if (err) + goto leave; + gcry_cipher_final (dfx->cipher_hd); + /* decrypt an empty string. */ + err = gcry_cipher_decrypt (dfx->cipher_hd, buf, 0, NULL, 0); + if (err) + { + log_debug ("gcry_cipher_decrypt failed (final): %s\n", + gpg_strerror (err)); + goto leave; + } + err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer+16, 16); + if (err) + { + log_debug ("gcry_cipher_checktag failed (final): %s\n", + gpg_strerror (err)); + /* Return Bad Signature like we do with MDC encryption. */ + if (gpg_err_code (err) == GPG_ERR_CHECKSUM) + err = gpg_error (GPG_ERR_BAD_SIGNATURE); + goto leave; + } + + n += off; + log_debug ("eof seen: returning %zu\n", n); + /* log_printhex (buf, n, "buf:"); */ + } + else + n += off; + } + + leave: + /* In case of a real error we better wipe out the buffer than to + * keep partly encrypted data. */ + if (err && gpg_err_code (err) != GPG_ERR_EOF) + memset (buf, 0, size); + *ret_len = n; + + return err; +} + + +/* The IOBUF filter used to decrypt AEAD encrypted data. */ +static int +aead_decode_filter (void *opaque, int control, IOBUF a, + byte *buf, size_t *ret_len) +{ + decode_filter_ctx_t dfx = opaque; + int rc = 0; + + if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen ) + { + *ret_len = 0; + rc = -1; + } + else if ( control == IOBUFCTRL_UNDERFLOW ) + { + log_assert (a); + + rc = aead_underflow (dfx, a, buf, ret_len); + if (gpg_err_code (rc) == GPG_ERR_EOF) + rc = -1; /* We need to use the old convention in the filter. */ + + } + else if ( control == IOBUFCTRL_FREE ) + { + release_dfx_context (dfx); + } + else if ( control == IOBUFCTRL_DESC ) + { + mem2str (buf, "aead_decode_filter", *ret_len); + } + + return rc; +} + static int mdc_decode_filter (void *opaque, int control, IOBUF a, @@ -365,6 +889,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a, } else { + memcpy (buf, dfx->defer, 22); } /* Fill up the buffer. */ diff --git a/g10/dek.h b/g10/dek.h index 64e98fc..1e861f5 100644 --- a/g10/dek.h +++ b/g10/dek.h @@ -32,8 +32,8 @@ typedef struct * verbose mode. */ int algo_info_printed : 1; - /* AEAD shall be used. */ - int use_aead : 1; + /* AEAD shall be used. The value is the AEAD algo. */ + int use_aead : 4; /* MDC shall be used. */ int use_mdc : 1; diff --git a/g10/encrypt.c b/g10/encrypt.c index 01feb4a..8568497 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -123,7 +123,7 @@ use_aead (pk_list_t pk_list, int algo) return 0; } - can_use = openpgp_cipher_get_algo_blklen (algo) != 16; + can_use = openpgp_cipher_get_algo_blklen (algo) == 16; /* With --force-mdc we clearly do not want AEAD. */ if (opt.force_mdc) @@ -133,12 +133,15 @@ use_aead (pk_list_t pk_list, int algo) if (opt.force_aead) { if (!can_use) - log_info ("Warning: request to use AEAD ignored for cipher '%s'\n", - openpgp_cipher_algo_name (algo)); + { + log_info ("Warning: request to use AEAD ignored for cipher '%s'\n", + openpgp_cipher_algo_name (algo)); + return 0; + } return 1; } - /* AEAD does noly work with 128 bit cipher blocklength. */ + /* AEAD does only work with 128 bit cipher blocklength. */ if (!can_use) return 0; @@ -307,7 +310,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) openpgp_cipher_algo_name (cfx.dek->algo)); if (use_aead (NULL, cfx.dek->algo)) - cfx.dek->use_aead = 1; + cfx.dek->use_aead = default_aead_algo (); else cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); } diff --git a/g10/filter.h b/g10/filter.h index 2924355..cd177f4 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -88,15 +88,52 @@ struct compress_filter_context_s { typedef struct compress_filter_context_s compress_filter_context_t; -typedef struct { - DEK *dek; - u32 datalen; - gcry_cipher_hd_t cipher_hd; - unsigned int wrote_header : 1; - unsigned int short_blklen_warn : 1; - unsigned long short_blklen_count; - gcry_md_hd_t mdc_hash; - byte enchash[20]; +typedef struct +{ + /* Object with the key and algo */ + DEK *dek; + + /* Length of the data to encrypt if known - 32 bit because OpenPGP + * requires partial encoding for a larger data size. */ + u32 datalen; + + /* The current cipher handle. */ + gcry_cipher_hd_t cipher_hd; + + /* Various processing flags. */ + unsigned int wrote_header : 1; + unsigned int short_blklen_warn : 1; + unsigned long short_blklen_count; + + /* The encoded chunk byte for AEAD. */ + byte chunkbyte; + + /* The decoded CHUNKBYTE. */ + uint64_t chunksize; + + /* The chunk index for AEAD. */ + uint64_t chunkindex; + + /* The number of bytes in the current chunk. */ + uint64_t chunklen; + + /* The total count of encrypted plaintext octets. Note that we + * don't care about encrypting more than 16 Exabyte. */ + uint64_t total; + + /* The hash context and a buffer used for MDC. */ + gcry_md_hd_t mdc_hash; + byte enchash[20]; + + /* The start IV for AEAD encryption. */ + byte startiv[16]; + + /* Using a large buffer for encryption makes processing easier and + * also makes sure the data is well aligned. */ + char *buffer; + size_t bufsize; /* Allocated length. */ + size_t buflen; /* Used length. */ + } cipher_filter_context_t; diff --git a/g10/gpg.c b/g10/gpg.c index a643388..2ae3e8a 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3882,7 +3882,7 @@ main (int argc, char **argv) /* Check our chosen algorithms against the list of legal algorithms. */ - if(!GNUPG) + if(!GNUPG && !opt.flags.rfc4880bis) { const char *badalg=NULL; preftype_t badtype=PREFTYPE_NONE; diff --git a/g10/mainproc.c b/g10/mainproc.c index b712e60..92da982 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -648,6 +648,7 @@ proc_encrypted (CTX c, PACKET *pkt) else if (!result && !opt.ignore_mdc_error && !pkt->pkt.encrypted->mdc_method + && !pkt->pkt.encrypted->aead_algo && openpgp_cipher_get_algo_blklen (c->dek->algo) != 8 && c->dek->algo != CIPHER_ALGO_TWOFISH) { @@ -662,17 +663,25 @@ proc_encrypted (CTX c, PACKET *pkt) write_status (STATUS_DECRYPTION_FAILED); } else if (!result || (gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE + && !pkt->pkt.encrypted->aead_algo && opt.ignore_mdc_error)) { + /* All is fine or for an MDC message the MDC failed but the + * --ignore-mdc-error option is active. For compatibility + * reasons we issue GOODMDC also for AEAD messages. */ write_status (STATUS_DECRYPTION_OKAY); if (opt.verbose > 1) log_info(_("decryption okay\n")); - if (pkt->pkt.encrypted->mdc_method && !result) + + if (pkt->pkt.encrypted->aead_algo) + write_status (STATUS_GOODMDC); + else if (pkt->pkt.encrypted->mdc_method && !result) write_status (STATUS_GOODMDC); else if (!opt.no_mdc_warn) log_info (_("WARNING: message was not integrity protected\n")); } - else if (gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE) + else if (gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE + || gpg_err_code (result) == GPG_ERR_TRUNCATED) { glo_ctrl.lasterr = result; log_error (_("WARNING: encrypted message has been manipulated!\n")); @@ -1391,7 +1400,8 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) case PKT_PUBKEY_ENC: proc_pubkey_enc (ctrl, c, pkt); break; case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break; case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break; + case PKT_ENCRYPTED_MDC: + case PKT_ENCRYPTED_AEAD:proc_encrypted (c, pkt); break; case PKT_COMPRESSED: rc = proc_compressed (c, pkt); break; default: newpkt = 0; break; } @@ -1407,6 +1417,7 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) case PKT_PUBKEY_ENC: case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: + case PKT_ENCRYPTED_AEAD: write_status_text( STATUS_UNEXPECTED, "0" ); rc = GPG_ERR_UNEXPECTED; goto leave; @@ -1434,7 +1445,8 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break; case PKT_PUBKEY_ENC: proc_pubkey_enc (ctrl, c, pkt); break; case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break; + case PKT_ENCRYPTED_MDC: + case PKT_ENCRYPTED_AEAD: proc_encrypted (c, pkt); break; case PKT_PLAINTEXT: proc_plaintext (c, pkt); break; case PKT_COMPRESSED: rc = proc_compressed (c, pkt); break; case PKT_ONEPASS_SIG: newpkt = add_onepass_sig (c, pkt); break; @@ -1461,7 +1473,8 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) case PKT_PUBKEY_ENC: proc_pubkey_enc (ctrl, c, pkt); break; case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break; case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break; + case PKT_ENCRYPTED_MDC: + case PKT_ENCRYPTED_AEAD: proc_encrypted (c, pkt); break; case PKT_PLAINTEXT: proc_plaintext (c, pkt); break; case PKT_COMPRESSED: rc = proc_compressed (c, pkt); break; case PKT_ONEPASS_SIG: newpkt = add_onepass_sig (c, pkt); break; diff --git a/g10/packet.h b/g10/packet.h index 894b389..4d15574 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -459,12 +459,13 @@ typedef struct { typedef struct { /* Remaining length of encrypted data. */ u32 len; - /* When encrypting, the first block size bytes of data are random - data and the following 2 bytes are copies of the last two bytes - of the random data (RFC 4880, Section 5.7). This provides a - simple check that the key is correct. extralen is the size of - this extra data. This is used by build_packet when writing out - the packet's header. */ + /* When encrypting in CFB mode, the first block size bytes of data + * are random data and the following 2 bytes are copies of the last + * two bytes of the random data (RFC 4880, Section 5.7). This + * provides a simple check that the key is correct. EXTRALEN is the + * size of this extra data or, in AEAD mode, the length of the + * headers and the tags. This is used by build_packet when writing + * out the packet's header. */ int extralen; /* Whether the serialized version of the packet used / should use the new format. */ @@ -476,6 +477,15 @@ typedef struct { /* If 0, MDC is disabled. Otherwise, the MDC method that was used (only DIGEST_ALGO_SHA1 has ever been defined). */ byte mdc_method; + /* If 0, AEAD is not used. Otherwise, the used AEAD algorithm. + * MDC_METHOD (above) shall be zero if AEAD is used. */ + byte aead_algo; + /* The cipher algo for/from the AEAD packet. 0 for other encryption + * packets. */ + byte cipher_algo; + /* The chunk byte from the AEAD packet. */ + byte chunkbyte; + /* An iobuf holding the data to be decrypted. (This is not used for encryption!) */ iobuf_t buf; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index eee14f6..de51770 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1,7 +1,6 @@ /* parse-packet.c - read packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2009, 2010 Free Software Foundation, Inc. - * Copyright (C) 2014 Werner Koch + * Copyright (C) 1998-2007, 2009-2010 Free Software Foundation, Inc. + * Copyright (C) 2014, 2018 Werner Koch * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. @@ -18,6 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0+ */ #include @@ -82,6 +82,9 @@ static int parse_compressed (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * packet, int new_ctb); static int parse_encrypted (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * packet, int new_ctb, int partial); +static gpg_error_t parse_encrypted_aead (IOBUF inp, int pkttype, + unsigned long pktlen, PACKET *packet, + int partial); static int parse_mdc (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * packet, int new_ctb); static int parse_gpg_control (IOBUF inp, int pkttype, unsigned long pktlen, @@ -636,6 +639,7 @@ parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos, case PKT_PLAINTEXT: case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: + case PKT_ENCRYPTED_AEAD: case PKT_COMPRESSED: iobuf_set_partial_body_length_mode (inp, c & 0xff); pktlen = 0; /* To indicate partial length. */ @@ -823,6 +827,9 @@ parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos, case PKT_MDC: rc = parse_mdc (inp, pkttype, pktlen, pkt, new_ctb); break; + case PKT_ENCRYPTED_AEAD: + rc = parse_encrypted_aead (inp, pkttype, pktlen, pkt, partial); + break; case PKT_GPG_CONTROL: rc = parse_gpg_control (inp, pkttype, pktlen, pkt, partial); break; @@ -1392,6 +1399,11 @@ dump_sig_subpkt (int hashed, int type, int critical, for (i = 0; i < length; i++) es_fprintf (listfp, " %d", buffer[i]); break; + case SIGSUBPKT_PREF_AEAD: + es_fputs ("pref-aead-algos:", listfp); + for (i = 0; i < length; i++) + es_fprintf (listfp, " %d", buffer[i]); + break; case SIGSUBPKT_REV_KEY: es_fputs ("revocation key: ", listfp); if (length < 22) @@ -1554,6 +1566,7 @@ parse_one_sig_subpkt (const byte * buffer, size_t n, int type) case SIGSUBPKT_KEY_FLAGS: case SIGSUBPKT_KS_FLAGS: case SIGSUBPKT_PREF_SYM: + case SIGSUBPKT_PREF_AEAD: case SIGSUBPKT_PREF_HASH: case SIGSUBPKT_PREF_COMPR: case SIGSUBPKT_POLICY: @@ -1636,6 +1649,7 @@ can_handle_critical (const byte * buffer, size_t n, int type) case SIGSUBPKT_ISSUER: /* issuer key ID */ case SIGSUBPKT_ISSUER_FPR: /* issuer fingerprint */ case SIGSUBPKT_PREF_SYM: + case SIGSUBPKT_PREF_AEAD: case SIGSUBPKT_PREF_HASH: case SIGSUBPKT_PREF_COMPR: case SIGSUBPKT_KEY_FLAGS: @@ -3161,6 +3175,9 @@ parse_encrypted (IOBUF inp, int pkttype, unsigned long pktlen, ed->buf = NULL; ed->new_ctb = new_ctb; ed->is_partial = partial; + ed->aead_algo = 0; + ed->cipher_algo = 0; /* Only used with AEAD. */ + ed->chunkbyte = 0; /* Only used with AEAD. */ if (pkttype == PKT_ENCRYPTED_MDC) { /* Fixme: add some pktlen sanity checks. */ @@ -3252,6 +3269,81 @@ parse_mdc (IOBUF inp, int pkttype, unsigned long pktlen, } +static gpg_error_t +parse_encrypted_aead (iobuf_t inp, int pkttype, unsigned long pktlen, + PACKET *pkt, int partial) +{ + int rc = 0; + PKT_encrypted *ed; + unsigned long orig_pktlen = pktlen; + int version; + + ed = pkt->pkt.encrypted = xtrymalloc (sizeof *pkt->pkt.encrypted); + if (!ed) + return gpg_error_from_syserror (); + ed->len = 0; + ed->extralen = 0; /* (only used in build_packet.) */ + ed->buf = NULL; + ed->new_ctb = 1; /* (packet number requires a new CTB anyway.) */ + ed->is_partial = partial; + ed->mdc_method = 0; + /* A basic sanity check. We need one version byte, one algo byte, + * one aead algo byte, one chunkbyte, at least 15 byte IV. */ + if (orig_pktlen && pktlen < 19) + { + log_error ("packet(%d) too short\n", pkttype); + if (list_mode) + es_fputs (":aead encrypted packet: [too short]\n", listfp); + rc = gpg_error (GPG_ERR_INV_PACKET); + iobuf_skip_rest (inp, pktlen, partial); + goto leave; + } + + version = iobuf_get_noeof (inp); + if (orig_pktlen) + pktlen--; + if (version != 1) + { + log_error ("aead encrypted packet with unknown version %d\n", + version); + if (list_mode) + es_fputs (":aead encrypted packet: [unknown version]\n", listfp); + /*skip_rest(inp, pktlen); should we really do this? */ + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + + ed->cipher_algo = iobuf_get_noeof (inp); + if (orig_pktlen) + pktlen--; + ed->aead_algo = iobuf_get_noeof (inp); + if (orig_pktlen) + pktlen--; + ed->chunkbyte = iobuf_get_noeof (inp); + if (orig_pktlen) + pktlen--; + + /* Store the remaining length of the encrypted data. We read the + * rest during decryption. */ + ed->len = pktlen; + + if (list_mode) + { + es_fprintf (listfp, ":aead encrypted packet: cipher=%u aead=%u cb=%u\n", + ed->cipher_algo, ed->aead_algo, ed->chunkbyte); + if (orig_pktlen) + es_fprintf (listfp, "\tlength: %lu\n", orig_pktlen); + else + es_fprintf (listfp, "\tlength: unknown\n"); + } + + ed->buf = inp; + + leave: + return rc; +} + + /* * This packet is internally generated by us (in armor.c) to transfer * some information to the lower layer. To make sure that this packet ----------------------------------------------------------------------- Summary of changes: common/openpgpdefs.h | 2 + doc/DETAILS | 7 +- g10/build-packet.c | 31 +++ g10/cipher-aead.c | 393 +++++++++++++++++++++++++++- g10/decrypt-data.c | 709 ++++++++++++++++++++++++++++++++++++++++++++------- g10/dek.h | 4 +- g10/encrypt.c | 13 +- g10/filter.h | 55 +++- g10/gpg.c | 2 +- g10/mainproc.c | 23 +- g10/packet.h | 22 +- g10/parse-packet.c | 98 ++++++- 12 files changed, 1228 insertions(+), 131 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jan 21 17:05:51 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 21 Jan 2018 17:05:51 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.3-118-g7356d6e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 7356d6ec50ea24bc9449187e1c2b3ecd717b789f (commit) from 3f4ca85cb0cf58006417f4f7faafaa9a1f1bdf22 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7356d6ec50ea24bc9449187e1c2b3ecd717b789f Author: Werner Koch Date: Sun Jan 21 16:42:29 2018 +0100 gpg: Support EAX if for latest Libgcrypt. * g10/cipher-aead.c (MY_GCRY_CIPHER_MODE_EAX): New. (write_header): Use it. * g10/decrypt-data.c (MY_GCRY_CIPHER_MODE_EAX): New. (decrypt_data): Use it. * g10/misc.c (openpgp_aead_test_algo): Allow EAX. -- This allows the use of EAX when the latest Libgcrypt master is used. Signed-off-by: Werner Koch diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index f247a83..1d72634 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -33,6 +33,11 @@ #include "options.h" #include "main.h" +/* FIXME: Libgcrypt 1.9 will support EAX. Until we kame this a + * requirement we hardwire the enum used for EAX. */ +#define MY_GCRY_CIPHER_MODE_EAX 14 + + /* The size of the buffer we allocate to encrypt the data. This must * be a multiple of the OCB blocksize (16 byte). */ #define AEAD_ENC_BUFFER_SIZE (64*1024) @@ -151,6 +156,11 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) startivlen = 15; break; + case AEAD_ALGO_EAX: + ciphermode = MY_GCRY_CIPHER_MODE_EAX; + startivlen = 16; + break; + default: log_error ("unsupported AEAD algo %d\n", cfx->dek->use_aead); err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 80e16ec..79e2554 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -31,6 +31,10 @@ #include "../common/status.h" #include "../common/compliance.h" +/* FIXME: Libgcrypt 1.9 will support EAX. Until we kame this a + * requirement we hardwire the enum used for EAX. */ +#define MY_GCRY_CIPHER_MODE_EAX 14 + static int aead_decode_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); @@ -278,9 +282,8 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) break; case AEAD_ALGO_EAX: startivlen = 16; - log_error ("unsupported AEAD algo %d\n", ed->aead_algo); - rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - goto leave; + ciphermode = MY_GCRY_CIPHER_MODE_EAX; + break; default: log_error ("unknown AEAD algo %d\n", ed->aead_algo); rc = gpg_error (GPG_ERR_INV_CIPHER_MODE); diff --git a/g10/misc.c b/g10/misc.c index 2da0d27..f7ac3c7 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -591,7 +591,6 @@ openpgp_aead_test_algo (aead_algo_t algo) case AEAD_ALGO_NONE: break; case AEAD_ALGO_EAX: - return gpg_error (GPG_ERR_NOT_SUPPORTED); case AEAD_ALGO_OCB: return 0; } ----------------------------------------------------------------------- Summary of changes: g10/cipher-aead.c | 10 ++++++++++ g10/decrypt-data.c | 9 ++++++--- g10/misc.c | 1 - 3 files changed, 16 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 22 11:47:14 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 22 Jan 2018 11:47:14 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-11-g91303b7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 91303b7df9c3e810cfcd4920f78bac6f8b7df2b2 (commit) from e1e35db510c9222e7a7dc208c2e49df556954170 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 91303b7df9c3e810cfcd4920f78bac6f8b7df2b2 Author: NIIBE Yutaka Date: Mon Jan 22 19:46:14 2018 +0900 scd: Support KDF Data Object of OpenPGPcard V3.3. * scd/app-openpgp.c (do_getattr, do_setattr): Add KDF support. (pin2hash_if_kdf): New. (verify_a_chv): Add PINLEN arg. Use pin2hash_if_kdf. (verify_chv2, do_sign): Follow the change of verify_a_chv. (verify_chv3, do_change_pin): Use pin2hash_if_kdf. -- GnuPG-bug-id: 3152 Signed-off-by: NIIBE Yutaka diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 6fcec3e..c9f2840 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -121,6 +121,7 @@ static struct { /* V3.0 */ { 0x7F74, 0, 0, 1, 0, 0, 0, 0, "General Feature Management"}, { 0x00D5, 0, 0, 1, 0, 0, 0, 0, "AES key data"}, + { 0x00F9, 0, 0, 1, 0, 0, 0, 0, "KDF data object"}, { 0 } }; @@ -199,7 +200,7 @@ struct app_local_s { unsigned int private_dos:1; unsigned int algo_attr_change:1; /* Algorithm attributes changeable. */ unsigned int has_decrypt:1; /* Support symmetric decryption. */ - unsigned int kdf_do:1; /* Support KDF DOs. */ + unsigned int kdf_do:1; /* Support KDF DO. */ unsigned int sm_algo:2; /* Symmetric crypto algo for SM. */ unsigned int pin_blk2:1; /* PIN block 2 format supported. */ @@ -980,6 +981,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) { "PRIVATE-DO-4", 0x0104 }, { "$AUTHKEYID", 0x0000, -3 }, { "$DISPSERIALNO",0x0000, -4 }, + { "KDF", 0x00F9 }, { NULL, 0 } }; int idx, i, rc; @@ -2054,6 +2056,47 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) return result; } +/* Compute hash if KDF-DO is available. CHVNO must be 0 for reset + code, 1 or 2 for user pin and 3 for admin pin. + */ +static gpg_error_t +pin2hash_if_kdf (app_t app, int chvno, char *pinvalue, int *r_pinlen) +{ + gpg_error_t err = 0; + void *relptr; + unsigned char *buffer; + size_t buflen; + + if (app->app_local->extcap.kdf_do + && (relptr = get_one_do (app, 0x00F9, &buffer, &buflen, NULL))) + { + char *salt; + unsigned long s2k_count; + char dek[32]; + + salt = &buffer[(chvno==3 ? 34 : (chvno==0 ? 24 : 14))]; + s2k_count = (((unsigned int)buffer[8] << 24) + | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]); + err = gcry_kdf_derive (pinvalue, strlen (pinvalue), + GCRY_KDF_ITERSALTED_S2K, + DIGEST_ALGO_SHA256, salt, 8, + s2k_count, sizeof (dek), dek); + if (!err) + { + /* pinvalue has a buffer of MAXLEN_PIN+1, 32 is OK. */ + *r_pinlen = 32; + memcpy (pinvalue, dek, *r_pinlen); + wipememory (dek, *r_pinlen); + } + + xfree (relptr); + } + else + *r_pinlen = strlen (pinvalue); + + return err; +} + /* Verify a CHV either using the pinentry or if possible by using a pinpad. PINCB and PINCB_ARG describe the usual callback @@ -2068,8 +2111,8 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) static gpg_error_t verify_a_chv (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), - void *pincb_arg, - int chvno, unsigned long sigcount, char **pinvalue) + void *pincb_arg, int chvno, unsigned long sigcount, + char **pinvalue, int *pinlen) { int rc = 0; char *prompt_buffer = NULL; @@ -2081,6 +2124,7 @@ verify_a_chv (app_t app, log_assert (chvno == 1 || chvno == 2); *pinvalue = NULL; + *pinlen = 0; remaining = get_remaining_tries (app, 0); if (remaining == -1) @@ -2169,8 +2213,9 @@ verify_a_chv (app_t app, return gpg_error (GPG_ERR_BAD_PIN); } - rc = iso7816_verify (app->slot, 0x80+chvno, - *pinvalue, strlen (*pinvalue)); + rc = pin2hash_if_kdf (app, chvno, *pinvalue, pinlen); + if (!rc) + rc = iso7816_verify (app->slot, 0x80+chvno, *pinvalue, *pinlen); } if (rc) @@ -2194,11 +2239,12 @@ verify_chv2 (app_t app, { int rc; char *pinvalue; + int pinlen; if (app->did_chv2) return 0; /* We already verified CHV2. */ - rc = verify_a_chv (app, pincb, pincb_arg, 2, 0, &pinvalue); + rc = verify_a_chv (app, pincb, pincb_arg, 2, 0, &pinvalue, &pinlen); if (rc) return rc; app->did_chv2 = 1; @@ -2209,7 +2255,7 @@ verify_chv2 (app_t app, the card is not configured to require a verification before each CHV1 controlled operation (force_chv1) and if we are not using the pinpad (PINVALUE == NULL). */ - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); + rc = iso7816_verify (app->slot, 0x81, pinvalue, pinlen); if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); if (rc) @@ -2319,6 +2365,7 @@ verify_chv3 (app_t app, else { char *pinvalue; + int pinlen; rc = pincb (pincb_arg, prompt, &pinvalue); xfree (prompt); @@ -2338,7 +2385,9 @@ verify_chv3 (app_t app, return gpg_error (GPG_ERR_BAD_PIN); } - rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue)); + rc = pin2hash_if_kdf (app, 3, pinvalue, &pinlen); + if (!rc) + rc = iso7816_verify (app->slot, 0x83, pinvalue, pinlen); xfree (pinvalue); } @@ -2389,6 +2438,7 @@ do_setattr (app_t app, const char *name, { "SM-KEY-MAC", 0x00D2, 3, 0, 1 }, { "KEY-ATTR", 0, 0, 3, 1 }, { "AESKEY", 0x00D5, 3, 0, 1 }, + { "KDF", 0x00F9, 3, 0, 1 }, { NULL, 0 } }; int exmode; @@ -2501,6 +2551,8 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, pininfo_t pininfo; int use_pinpad = 0; int minlen = 6; + int pinlen0 = 0; + int pinlen = 0; (void)ctrl; memset (&pininfo, 0, sizeof pininfo); @@ -2685,10 +2737,17 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, rc = gpg_error_from_syserror (); else { - strcpy (stpcpy (buffer, resetcode), pinvalue); - rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, - buffer, strlen (buffer)); - wipememory (buffer, strlen (buffer)); + strcpy (buffer, resetcode); + rc = pin2hash_if_kdf (app, 0, buffer, &pinlen0); + if (!rc) + { + strcpy (buffer+pinlen0, pinvalue); + rc = pin2hash_if_kdf (app, 0, buffer+pinlen0, &pinlen); + } + if (!rc) + rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, + buffer, pinlen0+pinlen); + wipememory (buffer, pinlen0 + pinlen); xfree (buffer); } } @@ -2700,16 +2759,19 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, rc = gpg_error (GPG_ERR_BAD_PIN); } else - rc = iso7816_put_data (app->slot, 0, 0xD3, - pinvalue, strlen (pinvalue)); + { + rc = pin2hash_if_kdf (app, 0, pinvalue, &pinlen); + if (!rc) + rc = iso7816_put_data (app->slot, 0, 0xD3, pinvalue, pinlen); + } } else if (reset_mode) { - rc = iso7816_reset_retry_counter (app->slot, 0x81, - pinvalue, strlen (pinvalue)); + rc = pin2hash_if_kdf (app, 1, pinvalue, &pinlen); + if (!rc) + rc = iso7816_reset_retry_counter (app->slot, 0x81, pinvalue, pinlen); if (!rc && !app->app_local->extcap.is_v2) - rc = iso7816_reset_retry_counter (app->slot, 0x82, - pinvalue, strlen (pinvalue)); + rc = iso7816_reset_retry_counter (app->slot, 0x82, pinvalue, pinlen); } else if (!app->app_local->extcap.is_v2) { @@ -2750,14 +2812,20 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ } else - rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, - oldpinvalue, strlen (oldpinvalue), - pinvalue, strlen (pinvalue)); + { + rc = pin2hash_if_kdf (app, chvno, oldpinvalue, &pinlen0); + if (!rc) + rc = pin2hash_if_kdf (app, chvno, pinvalue, &pinlen); + if (!rc) + rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, + oldpinvalue, pinlen0, + pinvalue, pinlen); + } } if (pinvalue) { - wipememory (pinvalue, strlen (pinvalue)); + wipememory (pinvalue, pinlen); xfree (pinvalue); } if (rc) @@ -2771,7 +2839,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } if (oldpinvalue) { - wipememory (oldpinvalue, strlen (oldpinvalue)); + wipememory (oldpinvalue, pinlen0); xfree (oldpinvalue); } return rc; @@ -4277,8 +4345,9 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, if (!app->did_chv1 || app->force_chv1 ) { char *pinvalue; + int pinlen; - rc = verify_a_chv (app, pincb, pincb_arg, 1, sigcount, &pinvalue); + rc = verify_a_chv (app, pincb, pincb_arg, 1, sigcount, &pinvalue, &pinlen); if (rc) return rc; @@ -4291,7 +4360,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, pinpad has been used. */ if (!app->did_chv2 && pinvalue && !app->app_local->extcap.is_v2) { - rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue)); + rc = iso7816_verify (app->slot, 0x82, pinvalue, pinlen); if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); if (rc) ----------------------------------------------------------------------- Summary of changes: scd/app-openpgp.c | 119 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 25 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 22 15:58:38 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 22 Jan 2018 15:58:38 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.3-119-g0131d43 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 0131d4369a81a51bf7bb328cc81a3bb082ed1a94 (commit) from 7356d6ec50ea24bc9449187e1c2b3ecd717b789f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0131d4369a81a51bf7bb328cc81a3bb082ed1a94 Author: Werner Koch Date: Mon Jan 22 15:50:24 2018 +0100 gpg: Refactor function encrypt_seskey. * g10/encrypt.c (encrypt_seskey): Allocate the buffer for the encrypted key and returns that buffer and its length. (encrypt_simple): Adjust for above change. (write_symkey_enc): Ditto. Signed-off-by: Werner Koch diff --git a/g10/encrypt.c b/g10/encrypt.c index 8568497..ab745ce 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -67,45 +67,75 @@ encrypt_store (const char *filename) } -/* *SESKEY contains the unencrypted session key ((*SESKEY)->KEY) and - the algorithm that will be used to encrypt the contents of the SED - packet ((*SESKEY)->ALGO). If *SESKEY is NULL, then a random - session key that is appropriate for DEK->ALGO is generated and - stored there. - - Encrypt that session key using DEK and store the result in ENCKEY, - which must be large enough to hold (*SESKEY)->KEYLEN + 1 bytes. */ -void -encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey) +/* Encrypt a session key using DEK and store a pointer to the result + * at R_ENCKEY and its length at R_ENCKEYLEN. + * + * R_SESKEY points to the unencrypted session key (.KEY, >KEYLEN) and + * the algorithm that will be used to encrypt the contents of the + * SKESK packet (.ALGO). If R_SESKEY points to NULL, then a random + * session key that is appropriate for DEK->ALGO is generated and + * stored at R_SESKEY. + */ +gpg_error_t +encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen) { - gcry_cipher_hd_t hd; - byte buf[33]; + gpg_error_t err; + gcry_cipher_hd_t hd = NULL; + byte *buf = NULL; + DEK *seskey; + + *r_enckey = NULL; + *r_enckeylen = 0; - log_assert ( dek->keylen <= 32 ); - if (!*seskey) + if (*r_seskey) + seskey = *r_seskey; + else { - *seskey=xmalloc_clear(sizeof(DEK)); - (*seskey)->algo=dek->algo; - make_session_key(*seskey); + seskey = xtrycalloc (1, sizeof(DEK)); + if (!seskey) + { + err = gpg_error_from_syserror (); + goto leave; + } + seskey->algo = dek->algo; + make_session_key (seskey); /*log_hexdump( "thekey", c->key, c->keylen );*/ } + buf = xtrymalloc_secure (1 + seskey->keylen); + if (!buf) + { + err = gpg_error_from_syserror (); + goto leave; + } + /* The encrypted session key is prefixed with a one-octet algorithm id. */ - buf[0] = (*seskey)->algo; - memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen ); - - /* We only pass already checked values to the following function, - thus we consider any failure as fatal. */ - if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) - BUG (); - if (gcry_cipher_setkey (hd, dek->key, dek->keylen)) - BUG (); - gcry_cipher_setiv (hd, NULL, 0); - gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0); - gcry_cipher_close (hd); + buf[0] = seskey->algo; + memcpy (buf + 1, seskey->key, seskey->keylen); + + err = openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1); + if (!err) + err = gcry_cipher_setkey (hd, dek->key, dek->keylen); + if (!err) + err = gcry_cipher_setiv (hd, NULL, 0); + if (!err) + err = gcry_cipher_encrypt (hd, buf, seskey->keylen + 1, NULL, 0); + if (err) + goto leave; + + *r_enckey = buf; + buf = NULL; + *r_enckeylen = seskey->keylen + 1; + /* Return the session key in case we allocated it. */ + *r_seskey = seskey; + seskey = NULL; - memcpy( enckey, buf, (*seskey)->keylen + 1 ); - wipememory( buf, sizeof buf ); /* burn key */ + leave: + gcry_cipher_close (hd); + if (seskey != *r_seskey) + xfree (seskey); + xfree (buf); + return err; } @@ -218,9 +248,9 @@ encrypt_simple (const char *filename, int mode, int use_seskey) PACKET pkt; PKT_plaintext *pt = NULL; STRING2KEY *s2k = NULL; - byte enckey[33]; + void *enckey = NULL; + size_t enckeylen = 0; int rc = 0; - int seskeylen = 0; u32 filesize; cipher_filter_context_t cfx; armor_filter_context_t *afx = NULL; @@ -273,6 +303,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) if ( mode ) { int canceled; + aead_algo_t aead_algo; s2k = xmalloc_clear( sizeof *s2k ); s2k->mode = opt.s2k_mode; @@ -296,21 +327,33 @@ encrypt_simple (const char *filename, int mode, int use_seskey) "due to the S2K mode\n")); } + /* See whether we want to use AEAD. */ + aead_algo = use_aead (NULL, cfx.dek->algo)? default_aead_algo () : 0; + if ( use_seskey ) { DEK *dek = NULL; - seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ()); - encrypt_seskey( cfx.dek, &dek, enckey ); - xfree( cfx.dek ); cfx.dek = dek; + rc = encrypt_seskey (cfx.dek, &dek, &enckey, &enckeylen); + if (rc) + { + xfree (cfx.dek); + xfree (s2k); + iobuf_close (inp); + release_progress_context (pfx); + return rc; + } + /* Replace key in DEK. */ + xfree (cfx.dek); + cfx.dek = dek; } if (opt.verbose) log_info(_("using cipher %s\n"), openpgp_cipher_algo_name (cfx.dek->algo)); - if (use_aead (NULL, cfx.dek->algo)) - cfx.dek->use_aead = default_aead_algo (); + if (aead_algo) + cfx.dek->use_aead = aead_algo; else cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); } @@ -342,20 +385,23 @@ encrypt_simple (const char *filename, int mode, int use_seskey) if ( s2k ) { - PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 ); + /* Fixme: This is quite similar to write_symkey_enc. */ + PKT_symkey_enc *enc = xmalloc_clear (sizeof *enc + enckeylen); enc->version = 4; enc->cipher_algo = cfx.dek->algo; enc->s2k = *s2k; - if ( use_seskey && seskeylen ) + if (enckeylen) { - enc->seskeylen = seskeylen + 1; /* algo id */ - memcpy (enc->seskey, enckey, seskeylen + 1 ); + enc->seskeylen = enckeylen; + memcpy (enc->seskey, enckey, enckeylen); } pkt.pkttype = PKT_SYMKEY_ENC; pkt.pkt.symkey_enc = enc; if ((rc = build_packet( out, &pkt ))) log_error("build symkey packet failed: %s\n", gpg_strerror (rc) ); xfree (enc); + xfree (enckey); + enckey = NULL; } if (!opt.no_literal) @@ -459,6 +505,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) if (pt) pt->buf = NULL; free_packet (&pkt, NULL); + xfree (enckey); xfree (cfx.dek); xfree (s2k); release_armor_context (afx); @@ -493,20 +540,29 @@ static int write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, iobuf_t out) { - int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo); - + int rc; + void *enckey; + size_t enckeylen; PKT_symkey_enc *enc; - byte enckey[33]; PACKET pkt; - enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1); - encrypt_seskey(symkey_dek,&dek,enckey); + rc = encrypt_seskey (symkey_dek, &dek, &enckey, &enckeylen); + if (rc) + return rc; + enc = xtrycalloc (1, sizeof (PKT_symkey_enc) + enckeylen); + if (!enc) + { + rc = gpg_error_from_syserror (); + xfree (enckey); + return rc; + } enc->version = 4; enc->cipher_algo = opt.s2k_cipher_algo; enc->s2k = *symkey_s2k; - enc->seskeylen = seskeylen + 1; /* algo id */ - memcpy( enc->seskey, enckey, seskeylen + 1 ); + enc->seskeylen = enckeylen; + memcpy (enc->seskey, enckey, enckeylen); + xfree (enckey); pkt.pkttype = PKT_SYMKEY_ENC; pkt.pkt.symkey_enc = enc; @@ -514,7 +570,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, if ((rc=build_packet(out,&pkt))) log_error("build symkey_enc packet failed: %s\n",gpg_strerror (rc)); - xfree(enc); + xfree (enc); return rc; } diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index f879838..f22c7c2 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -2283,9 +2283,11 @@ sk_esk (const char *option, int argc, char *argv[], void *cookie) DEK *sesdekp = &sesdek; /* Now encrypt the session key (or rather, the algorithm used to - encrypt the SED plus the session key) using ENCKEY. */ - ske->seskeylen = 1 + sesdek.keylen; - encrypt_seskey (&s2kdek, &sesdekp, ske->seskey); + encrypt the SKESK plus the session key) using ENCKEY. */ + err = encrypt_seskey (&s2kdek, &sesdekp, + (void**)&ske->seskey, (size_t *)&ske->seskeylen); + if (err) + log_fatal ("encrypt_seskey failed: %s\n", gpg_strerror (err)); /* Save the session key for later. */ session_key = sesdek; diff --git a/g10/main.h b/g10/main.h index 393a1b0..509126c 100644 --- a/g10/main.h +++ b/g10/main.h @@ -232,7 +232,8 @@ void display_online_help( const char *keyword ); /*-- encode.c --*/ int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); -void encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey); +gpg_error_t encrypt_seskey (DEK *dek, DEK **r_seskey, + void **r_enckey, size_t *r_enckeylen); int use_aead (pk_list_t pk_list, int algo); int use_mdc (pk_list_t pk_list,int algo); int encrypt_symmetric (const char *filename ); ----------------------------------------------------------------------- Summary of changes: g10/encrypt.c | 156 +++++++++++++++++++++++++++++++++++++------------------ g10/gpgcompose.c | 8 +-- g10/main.h | 3 +- 3 files changed, 113 insertions(+), 54 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 22 21:23:17 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Mon, 22 Jan 2018 21:23:17 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-40-g0b55f34 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 0b55f349a8b8f4b0ac9ed724c2d5b8dcc9f5401c (commit) via bd75f0e89817b5708c57efab49e3eb4e035186e2 (commit) via e8629e535bd0e9711b07904d4501de8ad57aaecd (commit) via cd7ed2e3546b12dd98df4211949f1cdbf5827013 (commit) from 93503c127a52c1f6a193750e2bf181a744ba3e6b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0b55f349a8b8f4b0ac9ed724c2d5b8dcc9f5401c Author: Jussi Kivilinna Date: Mon Jan 22 22:17:50 2018 +0200 Fix use of AVX instructions in Chaha20 SSSE3 implementation * cipher/chacha20-amd64-ssse3.S: Replace two 'vmovdqa' instructions with 'movdqa'. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/chacha20-amd64-ssse3.S b/cipher/chacha20-amd64-ssse3.S index 7ad1c0a..f237228 100644 --- a/cipher/chacha20-amd64-ssse3.S +++ b/cipher/chacha20-amd64-ssse3.S @@ -190,8 +190,8 @@ _gcry_chacha20_amd64_ssse3_blocks4: mov $20, ROUND; /* Construct counter vectors X12 and X13 */ - vmovdqa .Linc_counter RIP, X0; - vmovdqa .Lunsigned_cmp RIP, X2; + movdqa .Linc_counter RIP, X0; + movdqa .Lunsigned_cmp RIP, X2; pbroadcastd((12 * 4)(INPUT), X12); pbroadcastd((13 * 4)(INPUT), X13); paddd X0, X12; commit bd75f0e89817b5708c57efab49e3eb4e035186e2 Author: Jussi Kivilinna Date: Sat Jan 20 21:12:12 2018 +0200 doc: fix double "See" in front of reference * doc/gcrypt.texi: Change @xref to @ref when text already has 'see' in the front. -- @xref references start with `See ...'. Use @ref instead when text already has 'see' in front. Signed-off-by: Jussi Kivilinna diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index ccb4b82..bba07a4 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -1743,7 +1743,7 @@ other cipher functions and returns a handle to it in `hd'. In case of an error, an according error code is returned. The ID of algorithm to use must be specified via @var{algo}. See - at xref{Available ciphers}, for a list of supported ciphers and the + at ref{Available ciphers}, for a list of supported ciphers and the according constants. Besides using the constants directly, the function @@ -1751,7 +1751,7 @@ Besides using the constants directly, the function an algorithm into the according numeric ID. The cipher mode to use must be specified via @var{mode}. See - at xref{Available cipher modes}, for a list of supported cipher modes + at ref{Available cipher modes}, for a list of supported cipher modes and the according constants. Note that some modes are incompatible with some algorithms - in particular, stream mode (@code{GCRY_CIPHER_MODE_STREAM}) only works with stream ciphers. @@ -3310,7 +3310,7 @@ may be given as @code{0} if the algorithms to use are later set using @code{gcry_md_enable}. @var{hd} is guaranteed to either receive a valid handle or NULL. -For a list of supported algorithms, see @xref{Available hash +For a list of supported algorithms, see @ref{Available hash algorithms}. The flags allowed for @var{mode} are: @@ -3329,7 +3329,7 @@ algorithm is not an extendable-output function. Note that the function @code{gcry_md_setkey} must be used to set the MAC key. The size of the MAC is equal to the message digest of the underlying hash algorithm. If you want CBC message authentication codes based on a cipher, -see @xref{Working with cipher handles}. +see @ref{Working with cipher handles}. @item GCRY_MD_FLAG_BUGEMU1 @cindex bug emulation @@ -3847,7 +3847,7 @@ bitwise OR of constants described below. @var{hd} is guaranteed to either receive a valid handle or NULL. @var{ctx} is context object to associate MAC object with. @var{ctx} maybe set to NULL. -For a list of supported algorithms, see @xref{Available MAC algorithms}. +For a list of supported algorithms, see @ref{Available MAC algorithms}. The flags allowed for @var{mode} are: @@ -5626,7 +5626,7 @@ self-contained functions. Due to the wide variety of parameters required by different algorithms S-expressions, as flexible way to convey these parameters, are used. There is a set of helper functions to work with these S-expressions. - at c see @xref{S-expression Subsystem Architecture}. + at c see @ref{S-expression Subsystem Architecture}. Aside of functions to register new algorithms, map algorithms names to algorithms identifiers and to lookup properties of a key, the commit e8629e535bd0e9711b07904d4501de8ad57aaecd Author: Jussi Kivilinna Date: Sat Jan 20 21:08:37 2018 +0200 Add EAX mode * cipher/Makefile.am: Add 'cipher-eax.c'. * cipher/cipher-cmac.c (cmac_write): Rename to ... (_gcry_cmac_write): ... this; Take CMAC context as new input parameter; Return error code. (cmac_generate_subkeys): Rename to ... (_gcry_cmac_generate_subkeys): ... this; Take CMAC context as new input parameter; Return error code. (cmac_final): Rename to ... (_gcry_cmac_final): ... this; Take CMAC context as new input parameter; Return error code. (cmac_tag): Take CMAC context as new input parameter. (_gcry_cmac_reset): New. (_gcry_cipher_cmac_authenticate): Remove duplicate tag flag check; Adapt to changes above. (_gcry_cipher_cmac_get_tag): Adapt to changes above. (_gcry_cipher_cmac_check_tag): Ditto. (_gcry_cipher_cmac_set_subkeys): Ditto. * cipher-eax.c: New. * cipher-internal.h (gcry_cmac_context_t): New. (gcry_cipher_handle): Update u_mode.cmac; Add u_mode.eax. (_gcry_cmac_write, _gcry_cmac_generate_subkeys, _gcry_cmac_final) (_gcry_cmac_reset, _gcry_cipher_eax_encrypt, _gcry_cipher_eax_decrypt) (_gcry_cipher_eax_set_nonce, _gcry_cipher_eax_authenticate) (_gcry_cipher_eax_get_tag, _gcry_cipher_eax_check_tag) (_gcry_cipher_eax_setkey): New prototypes. * cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey) (cipher_reset, cipher_encrypt, cipher_decrypt, _gcry_cipher_setiv) (_gcry_cipher_authenticate, _gcry_cipher_gettag, _gcry_cipher_checktag) (_gcry_cipher_info): Add EAX mode. * doc/gcrypt.texi: Add EAX mode. * src/gcrypt.h.in (GCRY_CIPHER_MODE_EAX): New. * tests/basic.c (_check_gcm_cipher, _check_poly1305_cipher): Constify test vectors array. (_check_eax_cipher, check_eax_cipher): New. (check_ciphers, check_cipher_modes): Add EAX mode. * tests/bench-slope.c (bench_eax_encrypt_do_bench) (bench_eax_decrypt_do_bench, bench_eax_authenticate_do_bench) (eax_encrypt_ops, eax_decrypt_ops, eax_authenticate_ops): New. (cipher_modes): Add EAX mode. * tests/benchmark.c (cipher_bench): Add EAX mode. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/Makefile.am b/cipher/Makefile.am index bba815b..6e6c5ac 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -44,7 +44,7 @@ cipher.c cipher-internal.h \ cipher-cbc.c cipher-cfb.c cipher-ofb.c cipher-ctr.c cipher-aeswrap.c \ cipher-ccm.c cipher-cmac.c cipher-gcm.c cipher-gcm-intel-pclmul.c \ cipher-gcm-armv8-aarch32-ce.S cipher-gcm-armv8-aarch64-ce.S \ -cipher-poly1305.c cipher-ocb.c cipher-xts.c \ +cipher-poly1305.c cipher-ocb.c cipher-xts.c cipher-eax.c \ cipher-selftest.c cipher-selftest.h \ pubkey.c pubkey-internal.h pubkey-util.c \ md.c \ diff --git a/cipher/cipher-cmac.c b/cipher/cipher-cmac.c index da3ef75..30567b7 100644 --- a/cipher/cipher-cmac.c +++ b/cipher/cipher-cmac.c @@ -1,5 +1,5 @@ /* cmac.c - CMAC, Cipher-based MAC. - * Copyright (C) 2013 Jussi Kivilinna + * Copyright (C) 2013,2018 Jussi Kivilinna * * This file is part of Libgcrypt. * @@ -33,8 +33,9 @@ (burn) = (burn) > __nburn ? (burn) : __nburn; } while (0) -static void -cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen) +gcry_err_code_t +_gcry_cmac_write (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx, + const byte * inbuf, size_t inlen) { gcry_cipher_encrypt_t enc_fn = c->spec->encrypt; const unsigned int blocksize = c->spec->blocksize; @@ -42,31 +43,37 @@ cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen) unsigned int burn = 0; unsigned int nblocks; + if (ctx->tag) + return GPG_ERR_INV_STATE; + /* Tell compiler that we require a cipher with a 64bit or 128 bit block * length, to allow better optimization of this function. */ if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) - return; + return GPG_ERR_INV_CIPHER_MODE; - if (!inlen || !inbuf) - return; + if (!inbuf) + return GPG_ERR_INV_ARG; + + if (inlen == 0) + return 0; /* Last block is needed for cmac_final. */ - if (c->unused + inlen <= blocksize) + if (ctx->mac_unused + inlen <= blocksize) { - for (; inlen && c->unused < blocksize; inlen--) - c->lastiv[c->unused++] = *inbuf++; - return; + for (; inlen && ctx->mac_unused < blocksize; inlen--) + ctx->macbuf[ctx->mac_unused++] = *inbuf++; + return 0; } - if (c->unused) + if (ctx->mac_unused) { - for (; inlen && c->unused < blocksize; inlen--) - c->lastiv[c->unused++] = *inbuf++; + for (; inlen && ctx->mac_unused < blocksize; inlen--) + ctx->macbuf[ctx->mac_unused++] = *inbuf++; - buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); - set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv)); + buf_xor (ctx->u_iv.iv, ctx->u_iv.iv, ctx->macbuf, blocksize); + set_burn (burn, enc_fn (&c->context.c, ctx->u_iv.iv, ctx->u_iv.iv)); - c->unused = 0; + ctx->mac_unused = 0; } if (c->bulk.cbc_enc && inlen > blocksize) @@ -74,7 +81,7 @@ cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen) nblocks = inlen / blocksize; nblocks -= (nblocks * blocksize == inlen); - c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks, 1); + c->bulk.cbc_enc (&c->context.c, ctx->u_iv.iv, outbuf, inbuf, nblocks, 1); inbuf += nblocks * blocksize; inlen -= nblocks * blocksize; @@ -83,8 +90,8 @@ cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen) else while (inlen > blocksize) { - buf_xor (c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); - set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv)); + buf_xor (ctx->u_iv.iv, ctx->u_iv.iv, inbuf, blocksize); + set_burn (burn, enc_fn (&c->context.c, ctx->u_iv.iv, ctx->u_iv.iv)); inlen -= blocksize; inbuf += blocksize; } @@ -93,16 +100,18 @@ cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen) if (inlen == 0) BUG (); - for (; inlen && c->unused < blocksize; inlen--) - c->lastiv[c->unused++] = *inbuf++; + for (; inlen && ctx->mac_unused < blocksize; inlen--) + ctx->macbuf[ctx->mac_unused++] = *inbuf++; if (burn) _gcry_burn_stack (burn + 4 * sizeof (void *)); + + return 0; } -static void -cmac_generate_subkeys (gcry_cipher_hd_t c) +gcry_err_code_t +_gcry_cmac_generate_subkeys (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx) { const unsigned int blocksize = c->spec->blocksize; byte rb, carry, t, bi; @@ -117,7 +126,7 @@ cmac_generate_subkeys (gcry_cipher_hd_t c) /* Tell compiler that we require a cipher with a 64bit or 128 bit block * length, to allow better optimization of this function. */ if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) - return; + return GPG_ERR_INV_CIPHER_MODE; if (MAX_BLOCKSIZE < blocksize) BUG (); @@ -127,7 +136,7 @@ cmac_generate_subkeys (gcry_cipher_hd_t c) burn = c->spec->encrypt (&c->context.c, u.buf, u.buf); /* Currently supported blocksizes are 16 and 8. */ - rb = blocksize == 16 ? 0x87 : 0x1B /*blocksize == 8 */ ; + rb = blocksize == 16 ? 0x87 : 0x1B /* blocksize == 8 */ ; for (j = 0; j < 2; j++) { @@ -139,93 +148,113 @@ cmac_generate_subkeys (gcry_cipher_hd_t c) t = carry | (bi << 1); carry = bi >> 7; u.buf[i] = t & 0xff; - c->u_mode.cmac.subkeys[j][i] = u.buf[i]; + ctx->subkeys[j][i] = u.buf[i]; } u.buf[blocksize - 1] ^= carry ? rb : 0; - c->u_mode.cmac.subkeys[j][blocksize - 1] = u.buf[blocksize - 1]; + ctx->subkeys[j][blocksize - 1] = u.buf[blocksize - 1]; } wipememory (&u, sizeof (u)); if (burn) _gcry_burn_stack (burn + 4 * sizeof (void *)); + + return 0; } -static void -cmac_final (gcry_cipher_hd_t c) +gcry_err_code_t +_gcry_cmac_final (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx) { const unsigned int blocksize = c->spec->blocksize; - unsigned int count = c->unused; + unsigned int count = ctx->mac_unused; unsigned int burn; byte *subkey; /* Tell compiler that we require a cipher with a 64bit or 128 bit block * length, to allow better optimization of this function. */ if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1)) - return; + return GPG_ERR_INV_CIPHER_MODE; if (count == blocksize) - subkey = c->u_mode.cmac.subkeys[0]; /* K1 */ + subkey = ctx->subkeys[0]; /* K1 */ else { - subkey = c->u_mode.cmac.subkeys[1]; /* K2 */ - c->lastiv[count++] = 0x80; + subkey = ctx->subkeys[1]; /* K2 */ + ctx->macbuf[count++] = 0x80; while (count < blocksize) - c->lastiv[count++] = 0; + ctx->macbuf[count++] = 0; } - buf_xor (c->lastiv, c->lastiv, subkey, blocksize); + buf_xor (ctx->macbuf, ctx->macbuf, subkey, blocksize); - buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); - burn = c->spec->encrypt (&c->context.c, c->u_iv.iv, c->u_iv.iv); + buf_xor (ctx->u_iv.iv, ctx->u_iv.iv, ctx->macbuf, blocksize); + burn = c->spec->encrypt (&c->context.c, ctx->u_iv.iv, ctx->u_iv.iv); if (burn) _gcry_burn_stack (burn + 4 * sizeof (void *)); - c->unused = 0; + ctx->mac_unused = 0; + + return 0; } static gcry_err_code_t -cmac_tag (gcry_cipher_hd_t c, unsigned char *tag, size_t taglen, int check) +cmac_tag (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx, + unsigned char *tag, size_t taglen, int check) { + gcry_err_code_t ret; + if (!tag || taglen == 0 || taglen > c->spec->blocksize) return GPG_ERR_INV_ARG; - if (!c->u_mode.cmac.tag) + if (!ctx->tag) { - cmac_final (c); - c->u_mode.cmac.tag = 1; + ret = _gcry_cmac_final (c, ctx); + if (ret != 0) + return ret; + + ctx->tag = 1; } if (!check) { - memcpy (tag, c->u_iv.iv, taglen); + memcpy (tag, ctx->u_iv.iv, taglen); return GPG_ERR_NO_ERROR; } else { - return buf_eq_const (tag, c->u_iv.iv, taglen) ? + return buf_eq_const (tag, ctx->u_iv.iv, taglen) ? GPG_ERR_NO_ERROR : GPG_ERR_CHECKSUM; } } +void +_gcry_cmac_reset (gcry_cmac_context_t *ctx) +{ + char tmp_buf[sizeof(ctx->subkeys)]; + + /* Only keep subkeys when reseting context. */ + + buf_cpy (tmp_buf, ctx->subkeys, sizeof(ctx->subkeys)); + memset (ctx, 0, sizeof(*ctx)); + buf_cpy (ctx->subkeys, tmp_buf, sizeof(ctx->subkeys)); + wipememory (tmp_buf, sizeof(tmp_buf)); +} + + gcry_err_code_t _gcry_cipher_cmac_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen) { if (abuflen > 0 && !abuf) return GPG_ERR_INV_ARG; - if (c->u_mode.cmac.tag) - return GPG_ERR_INV_STATE; /* To support new blocksize, update cmac_generate_subkeys() then add new blocksize here. */ if (c->spec->blocksize != 16 && c->spec->blocksize != 8) return GPG_ERR_INV_CIPHER_MODE; - cmac_write (c, abuf, abuflen); - - return GPG_ERR_NO_ERROR; + return _gcry_cmac_write (c, &c->u_mode.cmac, abuf, abuflen); } @@ -233,7 +262,7 @@ gcry_err_code_t _gcry_cipher_cmac_get_tag (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen) { - return cmac_tag (c, outtag, taglen, 0); + return cmac_tag (c, &c->u_mode.cmac, outtag, taglen, 0); } @@ -241,13 +270,11 @@ gcry_err_code_t _gcry_cipher_cmac_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen) { - return cmac_tag (c, (unsigned char *) intag, taglen, 1); + return cmac_tag (c, &c->u_mode.cmac, (unsigned char *) intag, taglen, 1); } gcry_err_code_t _gcry_cipher_cmac_set_subkeys (gcry_cipher_hd_t c) { - cmac_generate_subkeys (c); - - return GPG_ERR_NO_ERROR; + return _gcry_cmac_generate_subkeys (c, &c->u_mode.cmac); } diff --git a/cipher/cipher-eax.c b/cipher/cipher-eax.c new file mode 100644 index 0000000..1ce4797 --- /dev/null +++ b/cipher/cipher-eax.c @@ -0,0 +1,248 @@ +/* cipher-eax.c - EAX implementation + * Copyright (C) 2018 Jussi Kivilinna + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser general Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include +#include +#include +#include + +#include "g10lib.h" +#include "cipher.h" +#include "bufhelp.h" +#include "./cipher-internal.h" + + +gcry_err_code_t +_gcry_cipher_eax_encrypt (gcry_cipher_hd_t c, + byte *outbuf, size_t outbuflen, + const byte *inbuf, size_t inbuflen) +{ + gcry_err_code_t err; + + if (outbuflen < inbuflen) + return GPG_ERR_BUFFER_TOO_SHORT; + if (c->marks.tag) + return GPG_ERR_INV_STATE; + + if (!c->marks.iv) + { + err = _gcry_cipher_eax_set_nonce (c, NULL, 0); + if (err != 0) + return err; + } + + err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); + if (err != 0) + return err; + + return _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, outbuf, inbuflen); +} + + +gcry_err_code_t +_gcry_cipher_eax_decrypt (gcry_cipher_hd_t c, + byte *outbuf, size_t outbuflen, + const byte *inbuf, size_t inbuflen) +{ + gcry_err_code_t err; + + if (outbuflen < inbuflen) + return GPG_ERR_BUFFER_TOO_SHORT; + if (c->marks.tag) + return GPG_ERR_INV_STATE; + + if (!c->marks.iv) + { + err = _gcry_cipher_eax_set_nonce (c, NULL, 0); + if (err != 0) + return err; + } + + err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, inbuf, inbuflen); + if (err != 0) + return err; + + return _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +} + + +gcry_err_code_t +_gcry_cipher_eax_authenticate (gcry_cipher_hd_t c, + const byte * aadbuf, size_t aadbuflen) +{ + gcry_err_code_t err; + + if (c->marks.tag) + return GPG_ERR_INV_STATE; + + if (!c->marks.iv) + { + err = _gcry_cipher_eax_set_nonce (c, NULL, 0); + if (err != 0) + return err; + } + + return _gcry_cmac_write (c, &c->u_mode.eax.cmac_header, aadbuf, aadbuflen); +} + + +gcry_err_code_t +_gcry_cipher_eax_setkey (gcry_cipher_hd_t c) +{ + gcry_err_code_t err; + + err = _gcry_cmac_generate_subkeys (c, &c->u_mode.eax.cmac_header); + if (err != 0) + return err; + + buf_cpy (c->u_mode.eax.cmac_ciphertext.subkeys, + c->u_mode.eax.cmac_header.subkeys, + sizeof(c->u_mode.eax.cmac_header.subkeys)); + + return 0; +} + + +gcry_err_code_t +_gcry_cipher_eax_set_nonce (gcry_cipher_hd_t c, const byte *nonce, + size_t noncelen) +{ + gcry_cmac_context_t nonce_cmac; + unsigned char initbuf[MAX_BLOCKSIZE]; + gcry_err_code_t err; + + c->marks.iv = 0; + c->marks.tag = 0; + + _gcry_cmac_reset (&c->u_mode.eax.cmac_header); + _gcry_cmac_reset (&c->u_mode.eax.cmac_ciphertext); + + /* Calculate nonce CMAC */ + + memset(&nonce_cmac, 0, sizeof(nonce_cmac)); + memset(&initbuf, 0, sizeof(initbuf)); + + buf_cpy (&nonce_cmac.subkeys, c->u_mode.eax.cmac_header.subkeys, + sizeof(c->u_mode.eax.cmac_header.subkeys)); + + err = _gcry_cmac_write (c, &nonce_cmac, initbuf, c->spec->blocksize); + if (err != 0) + return err; + + if (noncelen != 0) + { + err = _gcry_cmac_write (c, &nonce_cmac, nonce, noncelen); + if (err != 0) + return err; + } + + err = _gcry_cmac_final (c, &nonce_cmac); + if (err != 0) + return err; + + buf_cpy (c->u_iv.iv, nonce_cmac.u_iv.iv, MAX_BLOCKSIZE); + buf_cpy (c->u_ctr.ctr, nonce_cmac.u_iv.iv, MAX_BLOCKSIZE); + + wipememory (&nonce_cmac, sizeof(nonce_cmac)); + + /* Prepare header CMAC */ + + initbuf[c->spec->blocksize - 1] = 1; + err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_header, initbuf, + c->spec->blocksize); + if (err != 0) + return err; + + /* Prepare ciphertext CMAC */ + + initbuf[c->spec->blocksize - 1] = 2; + err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, initbuf, + c->spec->blocksize); + if (err != 0) + return err; + + c->marks.iv = 1; + c->marks.tag = 0; + + return 0; +} + + +static gcry_err_code_t +_gcry_cipher_eax_tag (gcry_cipher_hd_t c, + byte *outbuf, size_t outbuflen, int check) +{ + gcry_err_code_t err; + + if (!c->marks.tag) + { + err = _gcry_cmac_final (c, &c->u_mode.eax.cmac_header); + if (err != 0) + return err; + + err = _gcry_cmac_final (c, &c->u_mode.eax.cmac_ciphertext); + if (err != 0) + return err; + + buf_xor_1 (c->u_iv.iv, c->u_mode.eax.cmac_header.u_iv.iv, MAX_BLOCKSIZE); + buf_xor_1 (c->u_iv.iv, c->u_mode.eax.cmac_ciphertext.u_iv.iv, + MAX_BLOCKSIZE); + + _gcry_cmac_reset (&c->u_mode.eax.cmac_header); + _gcry_cmac_reset (&c->u_mode.eax.cmac_ciphertext); + + c->marks.tag = 1; + } + + if (!check) + { + if (outbuflen > c->spec->blocksize) + outbuflen = c->spec->blocksize; + + /* NB: We already checked that OUTBUF is large enough to hold + * the result or has valid truncated length. */ + memcpy (outbuf, c->u_iv.iv, outbuflen); + } + else + { + /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF + * and thus we need to compare its length first. */ + if (!(outbuflen <= c->spec->blocksize) + || !buf_eq_const (outbuf, c->u_iv.iv, outbuflen)) + return GPG_ERR_CHECKSUM; + } + + return 0; +} + + +gcry_err_code_t +_gcry_cipher_eax_get_tag (gcry_cipher_hd_t c, unsigned char *outtag, + size_t taglen) +{ + return _gcry_cipher_eax_tag (c, outtag, taglen, 0); +} + +gcry_err_code_t +_gcry_cipher_eax_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, + size_t taglen) +{ + return _gcry_cipher_eax_tag (c, (unsigned char *) intag, taglen, 1); +} diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index 8c897d7..a0ede5e 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -109,6 +109,25 @@ typedef union } cipher_context_alignment_t; +/* Storage structure for CMAC, for CMAC and EAX modes. */ +typedef struct { + /* The initialization vector. Also contains tag after finalization. */ + union { + cipher_context_alignment_t iv_align; + unsigned char iv[MAX_BLOCKSIZE]; + } u_iv; + + /* Subkeys for tag creation, not cleared by gcry_cipher_reset. */ + unsigned char subkeys[2][MAX_BLOCKSIZE]; + + /* Space to save partial input lengths for MAC. */ + unsigned char macbuf[MAX_BLOCKSIZE]; + + int mac_unused; /* Number of unprocessed bytes in MACBUF. */ + unsigned int tag:1; /* Set to 1 if tag has been finalized. */ +} gcry_cmac_context_t; + + /* The handle structure. */ struct gcry_cipher_handle { @@ -197,7 +216,7 @@ struct gcry_cipher_handle unsigned char s0[GCRY_CCM_BLOCK_LEN]; - unsigned int nonce:1;/* Set to 1 if nonce has been set. */ + unsigned int nonce:1; /* Set to 1 if nonce has been set. */ unsigned int lengths:1; /* Set to 1 if CCM length parameters has been processed. */ } ccm; @@ -217,12 +236,16 @@ struct gcry_cipher_handle } poly1305; /* Mode specific storage for CMAC mode. */ + gcry_cmac_context_t cmac; + + /* Mode specific storage for EAX mode. */ struct { - unsigned int tag:1; /* Set to 1 if tag has been finalized. */ + /* CMAC for header (AAD). */ + gcry_cmac_context_t cmac_header; - /* Subkeys for tag creation, not cleared by gcry_cipher_reset. */ - unsigned char subkeys[2][MAX_BLOCKSIZE]; - } cmac; + /* CMAC for ciphertext. */ + gcry_cmac_context_t cmac_ciphertext; + } eax; /* Mode specific storage for GCM mode. */ struct { @@ -236,7 +259,6 @@ struct gcry_cipher_handle unsigned char macbuf[GCRY_CCM_BLOCK_LEN]; int mac_unused; /* Number of unprocessed bytes in MACBUF. */ - /* byte counters for GCM */ u32 aadlen[2]; u32 datalen[2]; @@ -309,7 +331,6 @@ struct gcry_cipher_handle processed. */ unsigned int data_finalized:1; unsigned int aad_finalized:1; - } ocb; /* Mode specific storage for XTS mode. */ @@ -406,6 +427,42 @@ gcry_err_code_t _gcry_cipher_ccm_check_tag const unsigned char *intag, size_t taglen); +/*-- cipher-cmac.c --*/ +gcry_err_code_t _gcry_cmac_generate_subkeys +/* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx); +gcry_err_code_t _gcry_cmac_write +/* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx, + const byte * inbuf, size_t inlen); +gcry_err_code_t _gcry_cmac_final +/* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx); +void _gcry_cmac_reset (gcry_cmac_context_t *ctx); + + +/*-- cipher-eax.c --*/ +gcry_err_code_t _gcry_cipher_eax_encrypt +/* */ (gcry_cipher_hd_t c, + unsigned char *outbuf, size_t outbuflen, + const unsigned char *inbuf, size_t inbuflen); +gcry_err_code_t _gcry_cipher_eax_decrypt +/* */ (gcry_cipher_hd_t c, + unsigned char *outbuf, size_t outbuflen, + const unsigned char *inbuf, size_t inbuflen); +gcry_err_code_t _gcry_cipher_eax_set_nonce +/* */ (gcry_cipher_hd_t c, + const unsigned char *nonce, size_t noncelen); +gcry_err_code_t _gcry_cipher_eax_authenticate +/* */ (gcry_cipher_hd_t c, + const unsigned char *aadbuf, size_t aadbuflen); +gcry_err_code_t _gcry_cipher_eax_get_tag +/* */ (gcry_cipher_hd_t c, + unsigned char *outtag, size_t taglen); +gcry_err_code_t _gcry_cipher_eax_check_tag +/* */ (gcry_cipher_hd_t c, + const unsigned char *intag, size_t taglen); +gcry_err_code_t _gcry_cipher_eax_setkey +/* */ (gcry_cipher_hd_t c); + + /*-- cipher-gcm.c --*/ gcry_err_code_t _gcry_cipher_gcm_encrypt /* */ (gcry_cipher_hd_t c, diff --git a/cipher/cipher.c b/cipher/cipher.c index 18b2591..1bef766 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -420,6 +420,7 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle, case GCRY_CIPHER_MODE_CTR: case GCRY_CIPHER_MODE_AESWRAP: case GCRY_CIPHER_MODE_CMAC: + case GCRY_CIPHER_MODE_EAX: case GCRY_CIPHER_MODE_GCM: if (!spec->encrypt || !spec->decrypt) err = GPG_ERR_INV_CIPHER_MODE; @@ -688,7 +689,11 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen) switch (c->mode) { case GCRY_CIPHER_MODE_CMAC: - _gcry_cipher_cmac_set_subkeys (c); + rc = _gcry_cipher_cmac_set_subkeys (c); + break; + + case GCRY_CIPHER_MODE_EAX: + rc = _gcry_cipher_eax_setkey (c); break; case GCRY_CIPHER_MODE_GCM: @@ -782,8 +787,12 @@ cipher_reset (gcry_cipher_hd_t c) switch (c->mode) { case GCRY_CIPHER_MODE_CMAC: - /* Only clear 'tag' for cmac, keep subkeys. */ - c->u_mode.cmac.tag = 0; + _gcry_cmac_reset(&c->u_mode.cmac); + break; + + case GCRY_CIPHER_MODE_EAX: + _gcry_cmac_reset(&c->u_mode.eax.cmac_header); + _gcry_cmac_reset(&c->u_mode.eax.cmac_ciphertext); break; case GCRY_CIPHER_MODE_GCM: @@ -929,6 +938,10 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, rc = GPG_ERR_INV_CIPHER_MODE; break; + case GCRY_CIPHER_MODE_EAX: + rc = _gcry_cipher_eax_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); + break; + case GCRY_CIPHER_MODE_GCM: rc = _gcry_cipher_gcm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); break; @@ -1060,6 +1073,10 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, rc = GPG_ERR_INV_CIPHER_MODE; break; + case GCRY_CIPHER_MODE_EAX: + rc = _gcry_cipher_eax_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); + break; + case GCRY_CIPHER_MODE_GCM: rc = _gcry_cipher_gcm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); break; @@ -1158,6 +1175,10 @@ _gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen) rc = _gcry_cipher_ccm_set_nonce (hd, iv, ivlen); break; + case GCRY_CIPHER_MODE_EAX: + rc = _gcry_cipher_eax_set_nonce (hd, iv, ivlen); + break; + case GCRY_CIPHER_MODE_GCM: rc = _gcry_cipher_gcm_setiv (hd, iv, ivlen); break; @@ -1226,6 +1247,10 @@ _gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf, rc = _gcry_cipher_cmac_authenticate (hd, abuf, abuflen); break; + case GCRY_CIPHER_MODE_EAX: + rc = _gcry_cipher_eax_authenticate (hd, abuf, abuflen); + break; + case GCRY_CIPHER_MODE_GCM: rc = _gcry_cipher_gcm_authenticate (hd, abuf, abuflen); break; @@ -1263,6 +1288,10 @@ _gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen) rc = _gcry_cipher_cmac_get_tag (hd, outtag, taglen); break; + case GCRY_CIPHER_MODE_EAX: + rc = _gcry_cipher_eax_get_tag (hd, outtag, taglen); + break; + case GCRY_CIPHER_MODE_GCM: rc = _gcry_cipher_gcm_get_tag (hd, outtag, taglen); break; @@ -1300,6 +1329,10 @@ _gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen) rc = _gcry_cipher_cmac_check_tag (hd, intag, taglen); break; + case GCRY_CIPHER_MODE_EAX: + rc = _gcry_cipher_eax_check_tag (hd, intag, taglen); + break; + case GCRY_CIPHER_MODE_GCM: rc = _gcry_cipher_gcm_check_tag (hd, intag, taglen); break; @@ -1501,6 +1534,10 @@ _gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes) *nbytes = h->u_mode.ccm.authlen; break; + case GCRY_CIPHER_MODE_EAX: + *nbytes = h->spec->blocksize; + break; + case GCRY_CIPHER_MODE_GCM: *nbytes = GCRY_GCM_BLOCK_LEN; break; diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 7831505..ccb4b82 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -1722,6 +1722,12 @@ value is automatically incremented after each call of Auto-increment allows avoiding need of setting IV between processing of sequential data units. + at item GCRY_CIPHER_MODE_EAX + at cindex EAX, EAX mode +EAX is an Authenticated Encryption with Associated Data (AEAD) block cipher +mode by Bellare, Rogaway, and Wagner (see + at uref{http://web.cs.ucdavis.edu/~rogaway/papers/eax.html}). + @end table @node Working with cipher handles @@ -1752,12 +1758,13 @@ with some algorithms - in particular, stream mode Poly1305 AEAD mode (@code{GCRY_CIPHER_MODE_POLY1305}) only works with ChaCha20 stream cipher. The block cipher modes (@code{GCRY_CIPHER_MODE_ECB}, @code{GCRY_CIPHER_MODE_CBC}, - at code{GCRY_CIPHER_MODE_CFB}, @code{GCRY_CIPHER_MODE_OFB} and - at code{GCRY_CIPHER_MODE_CTR}) will work with any block cipher -algorithm. GCM mode (@code{GCRY_CIPHER_MODE_CCM}), CCM mode -(@code{GCRY_CIPHER_MODE_GCM}), OCB mode (@code{GCRY_CIPHER_MODE_OCB}), -and XTS mode (@code{GCRY_CIPHER_MODE_XTS}) will only work -with block cipher algorithms which have the block size of 16 bytes. + at code{GCRY_CIPHER_MODE_CFB}, @code{GCRY_CIPHER_MODE_OFB}, + at code{GCRY_CIPHER_MODE_CTR} and @code{GCRY_CIPHER_MODE_EAX}) will work +with any block cipher algorithm. GCM mode +(@code{GCRY_CIPHER_MODE_CCM}), CCM mode (@code{GCRY_CIPHER_MODE_GCM}), +OCB mode (@code{GCRY_CIPHER_MODE_OCB}), and XTS mode +(@code{GCRY_CIPHER_MODE_XTS}) will only work with block cipher +algorithms which have the block size of 16 bytes. The third argument @var{flags} can either be passed as @code{0} or as the bit-wise OR of the following constants. diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 1eb3d7c..83f94b6 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -971,7 +971,8 @@ enum gcry_cipher_modes GCRY_CIPHER_MODE_POLY1305 = 10, /* Poly1305 based AEAD mode. */ GCRY_CIPHER_MODE_OCB = 11, /* OCB3 mode. */ GCRY_CIPHER_MODE_CFB8 = 12, /* Cipher feedback (8 bit mode). */ - GCRY_CIPHER_MODE_XTS = 13 /* XTS mode. */ + GCRY_CIPHER_MODE_XTS = 13, /* XTS mode. */ + GCRY_CIPHER_MODE_EAX = 14 /* EAX mode. */ }; /* Flags used with the open function. */ diff --git a/tests/basic.c b/tests/basic.c index c2b4208..c883eb3 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1347,7 +1347,7 @@ check_ofb_cipher (void) static void _check_gcm_cipher (unsigned int step) { - struct tv + static const struct tv { int algo; char key[MAX_DATA_LEN]; @@ -1891,9 +1891,542 @@ check_gcm_cipher (void) static void +_check_eax_cipher (unsigned int step) +{ + static const struct tv + { + int algo; + char key[MAX_DATA_LEN]; + char nonce[MAX_DATA_LEN]; + int noncelen; + unsigned char header[MAX_DATA_LEN]; + int headerlen; + unsigned char plaintext[MAX_DATA_LEN]; + int inlen; + char out[MAX_DATA_LEN]; + char tag[MAX_DATA_LEN]; + int taglen; + int should_fail; + } tv[] = + { + /* Test vectors from http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf */ + { GCRY_CIPHER_AES, + "\x23\x39\x52\xDE\xE4\xD5\xED\x5F\x9B\x9C\x6D\x6F\xF8\x0F\xF4\x78", + "\x62\xEC\x67\xF9\xC3\xA4\xA4\x07\xFC\xB2\xA8\xC4\x90\x31\xA8\xB3", 16, + "\x6B\xFB\x91\x4F\xD0\x7E\xAE\x6B", 8, + "", + 0, + "", + "\xE0\x37\x83\x0E\x83\x89\xF2\x7B\x02\x5A\x2D\x65\x27\xE7\x9D\x01", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\x91\x94\x5D\x3F\x4D\xCB\xEE\x0B\xF4\x5E\xF5\x22\x55\xF0\x95\xA4", + "\xBE\xCA\xF0\x43\xB0\xA2\x3D\x84\x31\x94\xBA\x97\x2C\x66\xDE\xBD", 16, + "\xFA\x3B\xFD\x48\x06\xEB\x53\xFA", 8, + "\xF7\xFB", + 2, + "\x19\xDD", + "\x5C\x4C\x93\x31\x04\x9D\x0B\xDA\xB0\x27\x74\x08\xF6\x79\x67\xE5", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\x01\xF7\x4A\xD6\x40\x77\xF2\xE7\x04\xC0\xF6\x0A\xDA\x3D\xD5\x23", + "\x70\xC3\xDB\x4F\x0D\x26\x36\x84\x00\xA1\x0E\xD0\x5D\x2B\xFF\x5E", 16, + "\x23\x4A\x34\x63\xC1\x26\x4A\xC6", 8, + "\x1A\x47\xCB\x49\x33", + 5, + "\xD8\x51\xD5\xBA\xE0", + "\x3A\x59\xF2\x38\xA2\x3E\x39\x19\x9D\xC9\x26\x66\x26\xC4\x0F\x80", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\xD0\x7C\xF6\xCB\xB7\xF3\x13\xBD\xDE\x66\xB7\x27\xAF\xD3\xC5\xE8", + "\x84\x08\xDF\xFF\x3C\x1A\x2B\x12\x92\xDC\x19\x9E\x46\xB7\xD6\x17", 16, + "\x33\xCC\xE2\xEA\xBF\xF5\xA7\x9D", 8, + "\x48\x1C\x9E\x39\xB1", + 5, + "\x63\x2A\x9D\x13\x1A", + "\xD4\xC1\x68\xA4\x22\x5D\x8E\x1F\xF7\x55\x93\x99\x74\xA7\xBE\xDE", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\x35\xB6\xD0\x58\x00\x05\xBB\xC1\x2B\x05\x87\x12\x45\x57\xD2\xC2", + "\xFD\xB6\xB0\x66\x76\xEE\xDC\x5C\x61\xD7\x42\x76\xE1\xF8\xE8\x16", 16, + "\xAE\xB9\x6E\xAE\xBE\x29\x70\xE9", 8, + "\x40\xD0\xC0\x7D\xA5\xE4", + 6, + "\x07\x1D\xFE\x16\xC6\x75", + "\xCB\x06\x77\xE5\x36\xF7\x3A\xFE\x6A\x14\xB7\x4E\xE4\x98\x44\xDD", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\xBD\x8E\x6E\x11\x47\x5E\x60\xB2\x68\x78\x4C\x38\xC6\x2F\xEB\x22", + "\x6E\xAC\x5C\x93\x07\x2D\x8E\x85\x13\xF7\x50\x93\x5E\x46\xDA\x1B", 16, + "\xD4\x48\x2D\x1C\xA7\x8D\xCE\x0F", 8, + "\x4D\xE3\xB3\x5C\x3F\xC0\x39\x24\x5B\xD1\xFB\x7D", + 12, + "\x83\x5B\xB4\xF1\x5D\x74\x3E\x35\x0E\x72\x84\x14", + "\xAB\xB8\x64\x4F\xD6\xCC\xB8\x69\x47\xC5\xE1\x05\x90\x21\x0A\x4F", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\x7C\x77\xD6\xE8\x13\xBE\xD5\xAC\x98\xBA\xA4\x17\x47\x7A\x2E\x7D", + "\x1A\x8C\x98\xDC\xD7\x3D\x38\x39\x3B\x2B\xF1\x56\x9D\xEE\xFC\x19", 16, + "\x65\xD2\x01\x79\x90\xD6\x25\x28", 8, + "\x8B\x0A\x79\x30\x6C\x9C\xE7\xED\x99\xDA\xE4\xF8\x7F\x8D\xD6\x16\x36", + 17, + "\x02\x08\x3E\x39\x79\xDA\x01\x48\x12\xF5\x9F\x11\xD5\x26\x30\xDA\x30", + "\x13\x73\x27\xD1\x06\x49\xB0\xAA\x6E\x1C\x18\x1D\xB6\x17\xD7\xF2", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\x5F\xFF\x20\xCA\xFA\xB1\x19\xCA\x2F\xC7\x35\x49\xE2\x0F\x5B\x0D", + "\xDD\xE5\x9B\x97\xD7\x22\x15\x6D\x4D\x9A\xFF\x2B\xC7\x55\x98\x26", 16, + "\x54\xB9\xF0\x4E\x6A\x09\x18\x9A", 8, + "\x1B\xDA\x12\x2B\xCE\x8A\x8D\xBA\xF1\x87\x7D\x96\x2B\x85\x92\xDD" + "\x2D\x56", + 18, + "\x2E\xC4\x7B\x2C\x49\x54\xA4\x89\xAF\xC7\xBA\x48\x97\xED\xCD\xAE" + "\x8C\xC3", + "\x3B\x60\x45\x05\x99\xBD\x02\xC9\x63\x82\x90\x2A\xEF\x7F\x83\x2A", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\xA4\xA4\x78\x2B\xCF\xFD\x3E\xC5\xE7\xEF\x6D\x8C\x34\xA5\x61\x23", + "\xB7\x81\xFC\xF2\xF7\x5F\xA5\xA8\xDE\x97\xA9\xCA\x48\xE5\x22\xEC", 16, + "\x89\x9A\x17\x58\x97\x56\x1D\x7E", 8, + "\x6C\xF3\x67\x20\x87\x2B\x85\x13\xF6\xEA\xB1\xA8\xA4\x44\x38\xD5" + "\xEF\x11", + 18, + "\x0D\xE1\x8F\xD0\xFD\xD9\x1E\x7A\xF1\x9F\x1D\x8E\xE8\x73\x39\x38" + "\xB1\xE8", + "\xE7\xF6\xD2\x23\x16\x18\x10\x2F\xDB\x7F\xE5\x5F\xF1\x99\x17\x00", 16, + 0 + }, + { GCRY_CIPHER_AES, + "\x83\x95\xFC\xF1\xE9\x5B\xEB\xD6\x97\xBD\x01\x0B\xC7\x66\xAA\xC3", + "\x22\xE7\xAD\xD9\x3C\xFC\x63\x93\xC5\x7E\xC0\xB3\xC1\x7D\x6B\x44", 16, + "\x12\x67\x35\xFC\xC3\x20\xD2\x5A", 8, + "\xCA\x40\xD7\x44\x6E\x54\x5F\xFA\xED\x3B\xD1\x2A\x74\x0A\x65\x9F" + "\xFB\xBB\x3C\xEA\xB7", + 21, + "\xCB\x89\x20\xF8\x7A\x6C\x75\xCF\xF3\x96\x27\xB5\x6E\x3E\xD1\x97" + "\xC5\x52\xD2\x95\xA7", + "\xCF\xC4\x6A\xFC\x25\x3B\x46\x52\xB1\xAF\x37\x95\xB1\x24\xAB\x6E", 16, + 0 + }, + /* Negative test for bad tag. */ + { GCRY_CIPHER_AES, + "\x23\x39\x52\xDE\xE4\xD5\xED\x5F\x9B\x9C\x6D\x6F\xF8\x0F\xF4\x78", + "\x62\xEC\x67\xF9\xC3\xA4\xA4\x07\xFC\xB2\xA8\xC4\x90\x31\xA8\xB3", 16, + "\x6B\xFB\x91\x4F\xD0\x7E\xAE\x6B", 8, + "", + 0, + "", + "\x00\x37\x83\x0E\x83\x89\xF2\x7B\x02\x5A\x2D\x65\x27\xE7\x9D\x01", 16, + 1 + }, + /* Test vectors from libtomcrypt. */ + { + GCRY_CIPHER_AES, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "", 0, + "", 0, + "", + 0, + "", + "\x9a\xd0\x7e\x7d\xbf\xf3\x01\xf5\x05\xde\x59\x6b\x96\x15\xdf\xff", 16, + 0 + }, + { + GCRY_CIPHER_AES, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, + "", 0, + "", + 0, + "", + "\x1c\xe1\x0d\x3e\xff\xd4\xca\xdb\xe2\xe4\x4b\x58\xd6\x0a\xb9\xec", 16, + 0 + }, + { + GCRY_CIPHER_AES, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, + "", + 0, + "", + "\x3a\x69\x8f\x7a\x27\x0e\x51\xb0\xf6\x5b\x3d\x3e\x47\x19\x3c\xff", 16, + 0 + }, + { + GCRY_CIPHER_AES, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + 32, + "\x29\xd8\x78\xd1\xa3\xbe\x85\x7b\x6f\xb8\xc8\xea\x59\x50\xa7\x78" + "\x33\x1f\xbf\x2c\xcf\x33\x98\x6f\x35\xe8\xcf\x12\x1d\xcb\x30\xbc", + "\x4f\xbe\x03\x38\xbe\x1c\x8c\x7e\x1d\x7a\xe7\xe4\x5b\x92\xc5\x87", 16, + 0 + }, + { + GCRY_CIPHER_AES, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e", 15, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d", 14, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c", + 29, + "\xdd\x25\xc7\x54\xc5\xb1\x7c\x59\x28\xb6\x9b\x73\x15\x5f\x7b\xb8" + "\x88\x8f\xaf\x37\x09\x1a\xd9\x2c\x8a\x24\xdb\x86\x8b", + "\x0d\x1a\x14\xe5\x22\x24\xff\xd2\x3a\x05\xfa\x02\xcd\xef\x52\xda", 16, + 0 + }, + }; + + gcry_cipher_hd_t hde, hdd; + unsigned char out[MAX_DATA_LEN]; + unsigned char tag[16]; + int i, keylen; + gcry_error_t err = 0; + size_t pos, poslen, taglen2; + int byteNum; + + if (verbose) + fprintf (stderr, " Starting EAX checks.\n"); + + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { + if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + tv[i].algo); + continue; + } + + if (verbose) + fprintf (stderr, " checking EAX mode for %s [%i]\n", + gcry_cipher_algo_name (tv[i].algo), + tv[i].algo); + err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_EAX, 0); + if (!err) + err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_EAX, 0); + if (err) + { + fail ("aes-eax, gcry_cipher_open failed: %s\n", gpg_strerror (err)); + return; + } + + keylen = gcry_cipher_get_algo_keylen(tv[i].algo); + if (!keylen) + { + fail ("aes-eax, gcry_cipher_get_algo_keylen failed\n"); + return; + } + + err = gcry_cipher_setkey (hde, tv[i].key, keylen); + if (!err) + err = gcry_cipher_setkey (hdd, tv[i].key, keylen); + if (err) + { + fail ("aes-eax, gcry_cipher_setkey failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen); + if (!err) + err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen); + if (err) + { + fail ("aes-eax, gcry_cipher_setiv failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); + if (err) + { + fail ("cipher-eax, gcryctl_get_taglen failed (tv %d): %s\n", + i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + if (taglen2 != 16) + { + fail ("cipher-eax, gcryctl_get_taglen returned bad length" + " (tv %d): got=%zu want=%d\n", + i, taglen2, 16); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + for (pos = 0; pos < tv[i].headerlen; pos += step) + { + poslen = (pos + step < tv[i].headerlen) ? + step : tv[i].headerlen - pos; + + err = gcry_cipher_authenticate(hde, tv[i].header + pos, poslen); + if (err) + { + fail ("aes-eax, gcry_cipher_authenticate (%d) (%lu:%d) failed: " + "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + err = gcry_cipher_authenticate(hdd, tv[i].header + pos, poslen); + if (err) + { + fail ("aes-eax, de gcry_cipher_authenticate (%d) (%lu:%d) failed: " + "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + for (pos = 0; pos < tv[i].inlen; pos += step) + { + poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; + + err = gcry_cipher_encrypt (hde, out + pos, poslen, + tv[i].plaintext + pos, poslen); + if (err) + { + fail ("aes-eax, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n", + i, (unsigned long) pos, step, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + if (memcmp (tv[i].out, out, tv[i].inlen)) + fail ("aes-eax, encrypt mismatch entry %d (step %d)\n", i, step); + + for (pos = 0; pos < tv[i].inlen; pos += step) + { + poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; + + err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0); + if (err) + { + fail ("aes-eax, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n", + i, (unsigned long) pos, step, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + if (memcmp (tv[i].plaintext, out, tv[i].inlen)) + fail ("aes-eax, decrypt mismatch entry %d (step %d)\n", i, step); + + taglen2 = tv[i].taglen ? tv[i].taglen : 16; + + err = gcry_cipher_gettag (hde, out, taglen2); + if (err) + { + if (tv[i].should_fail) + goto next_tv; + + fail ("aes-eax, gcry_cipher_gettag(%d) failed: %s\n", + i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if ((memcmp (tv[i].tag, out, taglen2) != 0) ^ tv[i].should_fail) + fail ("aes-eax, encrypt tag mismatch entry %d\n", i); + + err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); + if (err) + { + if (tv[i].should_fail) + goto next_tv; + + fail ("aes-eax, gcry_cipher_checktag(%d) failed: %s\n", + i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + err = gcry_cipher_reset(hde); + if (!err) + err = gcry_cipher_reset(hdd); + if (err) + { + fail ("aes-eax, gcry_cipher_reset (%d) failed: %s\n", + i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + /* gcry_cipher_reset clears the IV */ + err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen); + if (!err) + err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen); + if (err) + { + fail ("aes-eax, gcry_cipher_setiv failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + /* this time we authenticate, encrypt and decrypt one byte at a time */ + for (byteNum = 0; byteNum < tv[i].headerlen; ++byteNum) + { + err = gcry_cipher_authenticate(hde, tv[i].header + byteNum, 1); + if (err) + { + fail ("aes-eax, gcry_cipher_authenticate (%d) (byte-buf) failed: " + "%s\n", i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + err = gcry_cipher_authenticate(hdd, tv[i].header + byteNum, 1); + if (err) + { + fail ("aes-eax, de gcry_cipher_authenticate (%d) (byte-buf) " + "failed: %s\n", i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) + { + err = gcry_cipher_encrypt (hde, out+byteNum, 1, + (tv[i].plaintext) + byteNum, + 1); + if (err) + { + fail ("aes-eax, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n", + i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + if (memcmp (tv[i].out, out, tv[i].inlen)) + fail ("aes-eax, encrypt mismatch entry %d, (byte-buf)\n", i); + + /* Test output to larger than 16-byte buffer. */ + taglen2 = tv[i].taglen ? tv[i].taglen : 16 + 1; + + err = gcry_cipher_gettag (hde, tag, taglen2); + if (err) + { + if (tv[i].should_fail) + goto next_tv; + + fail ("aes-eax, gcry_cipher_gettag(%d, %lu) (byte-buf) failed: %s\n", + i, (unsigned long) taglen2, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + taglen2 = tv[i].taglen ? tv[i].taglen : 16; + + if ((memcmp (tv[i].tag, tag, taglen2) != 0) ^ tv[i].should_fail) + fail ("aes-eax, encrypt tag mismatch entry %d, (byte-buf)\n", i); + + for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) + { + err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); + if (err) + { + fail ("aes-eax, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n", + i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + if (memcmp (tv[i].plaintext, out, tv[i].inlen)) + fail ("aes-eax, decrypt mismatch entry %d\n", i); + + err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); + if (err) + { + if (tv[i].should_fail) + goto next_tv; + + fail ("aes-eax, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n", + i, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + err = gcry_cipher_checktag (hdd, tag, 17); + if (!err) + { + fail ("aes-eax, gcry_cipher_checktag(%d) did not fail for invalid " + " tag length of '%d'\n", i, 17); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (tv[i].should_fail) + { + fail ("aes-eax, negative test succeeded %d\n", i); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + next_tv: + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + } + if (verbose) + fprintf (stderr, " Completed EAX checks.\n"); +} + + +static void +check_eax_cipher (void) +{ + /* Large buffers, no splitting. */ + _check_eax_cipher(0xffffffff); + /* Split input to one byte buffers. */ + _check_eax_cipher(1); + /* Split input to 7 byte buffers. */ + _check_eax_cipher(7); + /* Split input to 16 byte buffers. */ + _check_eax_cipher(16); +} + + +static void _check_poly1305_cipher (unsigned int step) { - struct tv + static const struct tv { int algo; const char *key; @@ -5813,6 +6346,7 @@ get_algo_mode_blklen (int algo, int mode) case GCRY_CIPHER_MODE_CTR: case GCRY_CIPHER_MODE_CCM: case GCRY_CIPHER_MODE_GCM: + case GCRY_CIPHER_MODE_EAX: case GCRY_CIPHER_MODE_POLY1305: return 1; } @@ -5894,7 +6428,7 @@ check_one_cipher_core (int algo, int mode, int flags, if ((mode == GCRY_CIPHER_MODE_CBC && (flags & GCRY_CIPHER_CBC_CTS)) || mode == GCRY_CIPHER_MODE_XTS) { - /* Input cannot be split in to multiple operations with CTS . */ + /* Input cannot be split in to multiple operations with CTS. */ blklen = nplain; } @@ -6281,6 +6815,7 @@ check_ciphers (void) check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_EAX, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) @@ -6333,6 +6868,7 @@ check_cipher_modes(void) check_poly1305_cipher (); check_ocb_cipher (); check_xts_cipher (); + check_eax_cipher (); check_gost28147_cipher (); check_stream_cipher (); check_stream_cipher_large_block (); diff --git a/tests/bench-slope.c b/tests/bench-slope.c index 75e6e43..e34104f 100644 --- a/tests/bench-slope.c +++ b/tests/bench-slope.c @@ -1231,6 +1231,53 @@ static struct bench_ops ocb_authenticate_ops = { &bench_ocb_authenticate_do_bench }; +static void +bench_eax_encrypt_do_bench (struct bench_obj *obj, void *buf, + size_t buflen) +{ + char nonce[16] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, + 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, + 0x00, 0x00, 0x01, 0x00 }; + bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce)); +} + +static void +bench_eax_decrypt_do_bench (struct bench_obj *obj, void *buf, + size_t buflen) +{ + char nonce[16] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, + 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, + 0x00, 0x00, 0x01, 0x00 }; + bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce)); +} + +static void +bench_eax_authenticate_do_bench (struct bench_obj *obj, void *buf, + size_t buflen) +{ + char nonce[16] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, + 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, + 0x00, 0x00, 0x01, 0x00 }; + bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce)); +} + +static struct bench_ops eax_encrypt_ops = { + &bench_encrypt_init, + &bench_encrypt_free, + &bench_eax_encrypt_do_bench +}; + +static struct bench_ops eax_decrypt_ops = { + &bench_encrypt_init, + &bench_encrypt_free, + &bench_eax_decrypt_do_bench +}; + +static struct bench_ops eax_authenticate_ops = { + &bench_encrypt_init, + &bench_encrypt_free, + &bench_eax_authenticate_do_bench +}; static void bench_poly1305_encrypt_do_bench (struct bench_obj *obj, void *buf, @@ -1291,6 +1338,9 @@ static struct bench_cipher_mode cipher_modes[] = { {GCRY_CIPHER_MODE_CCM, "CCM enc", &ccm_encrypt_ops}, {GCRY_CIPHER_MODE_CCM, "CCM dec", &ccm_decrypt_ops}, {GCRY_CIPHER_MODE_CCM, "CCM auth", &ccm_authenticate_ops}, + {GCRY_CIPHER_MODE_EAX, "EAX enc", &eax_encrypt_ops}, + {GCRY_CIPHER_MODE_EAX, "EAX dec", &eax_decrypt_ops}, + {GCRY_CIPHER_MODE_EAX, "EAX auth", &eax_authenticate_ops}, {GCRY_CIPHER_MODE_GCM, "GCM enc", &gcm_encrypt_ops}, {GCRY_CIPHER_MODE_GCM, "GCM dec", &gcm_decrypt_ops}, {GCRY_CIPHER_MODE_GCM, "GCM auth", &gcm_authenticate_ops}, diff --git a/tests/benchmark.c b/tests/benchmark.c index 44a8711..59ea32c 100644 --- a/tests/benchmark.c +++ b/tests/benchmark.c @@ -779,6 +779,8 @@ cipher_bench ( const char *algoname ) NULL, GCRY_GCM_BLOCK_LEN, GCRY_GCM_BLOCK_LEN }, { GCRY_CIPHER_MODE_OCB, " OCB", 1, NULL, 16, 16, 15 }, + { GCRY_CIPHER_MODE_EAX, " EAX", 0, + NULL, 0, 8, 8 }, { GCRY_CIPHER_MODE_STREAM, "", 0 }, {0} }; commit cd7ed2e3546b12dd98df4211949f1cdbf5827013 Author: Jussi Kivilinna Date: Sun Jan 7 22:19:13 2018 +0200 cipher: constify spec arrays * cipher/cipher.c (cipher_list): Constify array. * cipher/mac.c (mac_list): Constify array. * cipher/md.c (digest_list): Constify array. * cipher/pubkey.c (pubkey_list): Constify array. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/cipher.c b/cipher/cipher.c index 063c13d..18b2591 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -33,7 +33,7 @@ /* This is the list of the default ciphers, which are included in libgcrypt. */ -static gcry_cipher_spec_t *cipher_list[] = +static gcry_cipher_spec_t * const cipher_list[] = { #if USE_BLOWFISH &_gcry_cipher_spec_blowfish, diff --git a/cipher/mac.c b/cipher/mac.c index 46be7b7..4a7a47d 100644 --- a/cipher/mac.c +++ b/cipher/mac.c @@ -29,7 +29,7 @@ /* This is the list of the digest implementations included in libgcrypt. */ -static gcry_mac_spec_t *mac_list[] = { +static gcry_mac_spec_t * const mac_list[] = { #if USE_SHA1 &_gcry_mac_type_spec_hmac_sha1, #endif diff --git a/cipher/md.c b/cipher/md.c index 94f1b5d..efbffe1 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -31,7 +31,7 @@ /* This is the list of the digest implementations included in libgcrypt. */ -static gcry_md_spec_t *digest_list[] = +static gcry_md_spec_t * const digest_list[] = { #if USE_CRC &_gcry_digest_spec_crc32, diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 8ec15fd..4c07e33 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -34,7 +34,7 @@ /* This is the list of the public-key algorithms included in Libgcrypt. */ -static gcry_pk_spec_t *pubkey_list[] = +static gcry_pk_spec_t * const pubkey_list[] = { #if USE_ECC &_gcry_pubkey_spec_ecc, ----------------------------------------------------------------------- Summary of changes: cipher/Makefile.am | 2 +- cipher/chacha20-amd64-ssse3.S | 4 +- cipher/cipher-cmac.c | 137 ++++++----- cipher/cipher-eax.c | 248 +++++++++++++++++++ cipher/cipher-internal.h | 71 +++++- cipher/cipher.c | 45 +++- cipher/mac.c | 2 +- cipher/md.c | 2 +- cipher/pubkey.c | 2 +- doc/gcrypt.texi | 31 ++- src/gcrypt.h.in | 3 +- tests/basic.c | 542 +++++++++++++++++++++++++++++++++++++++++- tests/bench-slope.c | 50 ++++ tests/benchmark.c | 2 + 14 files changed, 1053 insertions(+), 88 deletions(-) create mode 100644 cipher/cipher-eax.c hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 23 12:58:13 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 23 Jan 2018 12:58:13 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.3-123-g112e02e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 112e02ee89b78369c1c50e672873e726cbfeb994 (commit) via 278d87465685e0aa415e0333de1d27e79d1608f0 (commit) via 9aab9167bca38323973e853845ca95ae8e9b6871 (commit) via da3015e3c05030fe709c8f922486e73d06d1d16a (commit) from 0131d4369a81a51bf7bb328cc81a3bb082ed1a94 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 112e02ee89b78369c1c50e672873e726cbfeb994 Author: Werner Koch Date: Tue Jan 23 12:50:11 2018 +0100 gpg: Copy the AEAD prefs to the user ID struct. * g10/getkey.c (fixup_uidnode): Copy the AEAD prefs. -- With this patch AEAD preferences are now properly created and displayed. Signed-off-by: Werner Koch diff --git a/g10/getkey.c b/g10/getkey.c index 497dace..a838c3c 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2443,8 +2443,8 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated) { PKT_user_id *uid = uidnode->pkt->pkt.user_id; PKT_signature *sig = signode->pkt->pkt.signature; - const byte *p, *sym, *hash, *zip; - size_t n, nsym, nhash, nzip; + const byte *p, *sym, *aead, *hash, *zip; + size_t n, nsym, naead, nhash, nzip; sig->flags.chosen_selfsig = 1;/* We chose this one. */ uid->created = 0; /* Not created == invalid. */ @@ -2499,6 +2499,9 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated) p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_SYM, &n); sym = p; nsym = p ? n : 0; + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_AEAD, &n); + aead = p; + naead = p ? n : 0; p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_HASH, &n); hash = p; nhash = p ? n : 0; @@ -2507,7 +2510,7 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated) nzip = p ? n : 0; if (uid->prefs) xfree (uid->prefs); - n = nsym + nhash + nzip; + n = nsym + naead + nhash + nzip; if (!n) uid->prefs = NULL; else @@ -2519,6 +2522,11 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated) uid->prefs[n].type = PREFTYPE_SYM; uid->prefs[n].value = *sym++; } + for (; naead; naead--, n++) + { + uid->prefs[n].type = PREFTYPE_AEAD; + uid->prefs[n].value = *aead++; + } for (; nhash; nhash--, n++) { uid->prefs[n].type = PREFTYPE_HASH; commit 278d87465685e0aa415e0333de1d27e79d1608f0 Author: Werner Koch Date: Tue Jan 23 11:54:02 2018 +0100 gpg: Clear the symmetric passphrase cache for encrypted session keys. * g10/mainproc.c (proc_symkey_enc): Clear the symmetric key cache on error. (proc_encrypted): Need to take are of the checksum error. Signed-off-by: Werner Koch diff --git a/g10/mainproc.c b/g10/mainproc.c index d1d44d7..accf25e 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -252,7 +252,6 @@ symkey_decrypt_seskey (DEK *dek, byte *seskey, size_t slen) gcry_cipher_hd_t hd; unsigned int noncelen, keylen; enum gcry_cipher_modes ciphermode; - byte ad[4]; if (dek->use_aead) { @@ -410,9 +409,17 @@ proc_symkey_enc (CTX c, PACKET *pkt) log_info ("decryption of the symmetrically encrypted" " session key failed: %s\n", gpg_strerror (err)); - if (gpg_err_code (err) != GPG_ERR_BAD_KEY) + if (gpg_err_code (err) != GPG_ERR_BAD_KEY + && gpg_err_code (err) != GPG_ERR_CHECKSUM) log_fatal ("process terminated to be bug compatible" " with GnuPG <= 2.2\n"); + if (c->dek->s2k_cacheid[0]) + { + if (opt.debug) + log_debug ("cleared passphrase cached with ID:" + " %s\n", c->dek->s2k_cacheid); + passphrase_clear_cache (c->dek->s2k_cacheid); + } xfree (c->dek); c->dek = NULL; } @@ -757,6 +764,7 @@ proc_encrypted (CTX c, PACKET *pkt) else { if ((gpg_err_code (result) == GPG_ERR_BAD_KEY + || gpg_err_code (result) == GPG_ERR_CHECKSUM || gpg_err_code (result) == GPG_ERR_CIPHER_ALGO) && *c->dek->s2k_cacheid != '\0') { commit 9aab9167bca38323973e853845ca95ae8e9b6871 Author: Werner Koch Date: Tue Jan 23 12:07:25 2018 +0100 gpg: Implement AEAD for SKESK packets. * g10/packet.h (PKT_symkey_enc): Add field aead_algo. * g10/build-packet.c (do_symkey_enc): Support version 5 packets. * g10/parse-packet.c (parse_symkeyenc): Ditto. * g10/encrypt.c (encrypt_symmetric): Force using a random session key in AEAD mode. (encrypt_seskey): Add and support arg aead_algo. (write_symkey_enc): Ditto. (encrypt_simple): Adjust accordingly. (encrypt_filter): Ditto. * g10/gpgcompose.c (sk_esk): For now call encrypt_seskey without AEAD support. * g10/mainproc.c (symkey_decrypt_seskey): Support AEAD. Nver call BUG but return an error. (proc_symkey_enc): Call symkey_decrypt_seskey in a bug compatible way. * g10/import.c (check_prefs): Check AEAD preferences. * g10/keyedit.c (show_prefs): Print AEAD preferences. -- For easier debugging this patch also changes some diagnostics to also print the encryption mode with the cipher algorithm. Signed-off-by: Werner Koch diff --git a/g10/build-packet.c b/g10/build-packet.c index fc64c9c..b4e03d0 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -617,11 +617,8 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc ) IOBUF a = iobuf_temp(); log_assert (ctb_pkttype (ctb) == PKT_SYMKEY_ENC); + log_assert (enc->version == 4 || enc->version == 5); - /* The only acceptable version. */ - log_assert( enc->version == 4 ); - - /* RFC 4880, Section 3.7. */ switch (enc->s2k.mode) { case 0: /* Simple S2K. */ @@ -632,23 +629,26 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc ) default: log_bug ("do_symkey_enc: s2k=%d\n", enc->s2k.mode); } - iobuf_put( a, enc->version ); - iobuf_put( a, enc->cipher_algo ); - iobuf_put( a, enc->s2k.mode ); - iobuf_put( a, enc->s2k.hash_algo ); - if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) { - iobuf_write(a, enc->s2k.salt, 8 ); - if( enc->s2k.mode == 3 ) - iobuf_put(a, enc->s2k.count); + iobuf_put (a, enc->version); + iobuf_put (a, enc->cipher_algo); + if (enc->version == 5) + iobuf_put (a, enc->aead_algo); + iobuf_put (a, enc->s2k.mode); + iobuf_put (a, enc->s2k.hash_algo); + if (enc->s2k.mode == 1 || enc->s2k.mode == 3) + { + iobuf_write (a, enc->s2k.salt, 8); + if (enc->s2k.mode == 3) + iobuf_put (a, enc->s2k.count); } - if( enc->seskeylen ) - iobuf_write(a, enc->seskey, enc->seskeylen ); + if (enc->seskeylen) + iobuf_write (a, enc->seskey, enc->seskeylen); - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp( out, a ); + write_header (out, ctb, iobuf_get_temp_length(a)); + rc = iobuf_write_temp (out, a); - iobuf_close(a); - return rc; + iobuf_close (a); + return rc; } diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 7ed0bf0..46650f2 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -212,8 +212,10 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) if ( opt.verbose && !dek->algo_info_printed ) { if (!openpgp_cipher_test_algo (dek->algo)) - log_info (_("%s encrypted data\n"), - openpgp_cipher_algo_name (dek->algo)); + log_info (_("%s.%s encrypted data\n"), + openpgp_cipher_algo_name (dek->algo), + ed->aead_algo? openpgp_aead_algo_name (ed->aead_algo) + /**/ : "CFB"); else log_info (_("encrypted with unknown algorithm %d\n"), dek->algo ); dek->algo_info_printed = 1; diff --git a/g10/encrypt.c b/g10/encrypt.c index 4cc4b1a..c6c9e3a 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -47,12 +47,12 @@ static int write_pubkey_enc_from_list (ctrl_t ctrl, /**************** * Encrypt FILENAME with only the symmetric cipher. Take input from - * stdin if FILENAME is NULL. + * stdin if FILENAME is NULL. If --force-aead is used we use an SKESK. */ int encrypt_symmetric (const char *filename) { - return encrypt_simple( filename, 1, 0 ); + return encrypt_simple( filename, 1, opt.force_aead); } @@ -70,14 +70,16 @@ encrypt_store (const char *filename) /* Encrypt a session key using DEK and store a pointer to the result * at R_ENCKEY and its length at R_ENCKEYLEN. * - * R_SESKEY points to the unencrypted session key (.KEY, >KEYLEN) and + * R_SESKEY points to the unencrypted session key (.KEY, .KEYLEN) and * the algorithm that will be used to encrypt the contents of the * SKESK packet (.ALGO). If R_SESKEY points to NULL, then a random * session key that is appropriate for DEK->ALGO is generated and - * stored at R_SESKEY. + * stored at R_SESKEY. If AEAD_ALGO is not 0 the given AEAD algorithm + * is used for encryption. */ gpg_error_t -encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen) +encrypt_seskey (DEK *dek, aead_algo_t aead_algo, + DEK **r_seskey, void **r_enckey, size_t *r_enckeylen) { gpg_error_t err; gcry_cipher_hd_t hd = NULL; @@ -102,30 +104,84 @@ encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen) /*log_hexdump( "thekey", c->key, c->keylen );*/ } - buf = xtrymalloc_secure (1 + seskey->keylen); - if (!buf) + + if (aead_algo) { - err = gpg_error_from_syserror (); - goto leave; - } + unsigned int noncelen; + enum gcry_cipher_modes ciphermode; + byte ad[4]; + + err = openpgp_aead_algo_info (aead_algo, &ciphermode, &noncelen); + if (err) + goto leave; + + /* Allocate space for the nonce, the key, and the authentication + * tag (16). */ + buf = xtrymalloc_secure (noncelen + seskey->keylen + 16); + if (!buf) + { + err = gpg_error_from_syserror (); + goto leave; + } - /* The encrypted session key is prefixed with a one-octet algorithm id. */ - buf[0] = seskey->algo; - memcpy (buf + 1, seskey->key, seskey->keylen); - - err = openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1); - if (!err) - err = gcry_cipher_setkey (hd, dek->key, dek->keylen); - if (!err) - err = gcry_cipher_setiv (hd, NULL, 0); - if (!err) - err = gcry_cipher_encrypt (hd, buf, seskey->keylen + 1, NULL, 0); - if (err) - goto leave; + gcry_randomize (buf, noncelen, GCRY_STRONG_RANDOM); + + err = openpgp_cipher_open (&hd, dek->algo, + ciphermode, GCRY_CIPHER_SECURE); + if (!err) + err = gcry_cipher_setkey (hd, dek->key, dek->keylen); + if (!err) + err = gcry_cipher_setiv (hd, buf, noncelen); + if (err) + goto leave; + + ad[0] = (0xc0 | PKT_SYMKEY_ENC); + ad[1] = 5; + ad[2] = dek->algo; + ad[3] = aead_algo; + err = gcry_cipher_authenticate (hd, ad, 4); + if (err) + goto leave; + + memcpy (buf + noncelen, seskey->key, seskey->keylen); + gcry_cipher_final (hd); + err = gcry_cipher_encrypt (hd, buf + noncelen, seskey->keylen, NULL,0); + if (err) + goto leave; + err = gcry_cipher_gettag (hd, buf + noncelen + seskey->keylen, 16); + if (err) + goto leave; + *r_enckeylen = noncelen + seskey->keylen + 16; + *r_enckey = buf; + buf = NULL; + } + else + { + /* In the old version 4 SKESK the encrypted session key is + * prefixed with a one-octet algorithm id. */ + buf = xtrymalloc_secure (1 + seskey->keylen); + if (!buf) + { + err = gpg_error_from_syserror (); + goto leave; + } + buf[0] = seskey->algo; + memcpy (buf + 1, seskey->key, seskey->keylen); + + err = openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1); + if (!err) + err = gcry_cipher_setkey (hd, dek->key, dek->keylen); + if (!err) + err = gcry_cipher_setiv (hd, NULL, 0); + if (!err) + err = gcry_cipher_encrypt (hd, buf, seskey->keylen + 1, NULL, 0); + if (err) + goto leave; + *r_enckeylen = seskey->keylen + 1; + *r_enckey = buf; + buf = NULL; + } - *r_enckey = buf; - buf = NULL; - *r_enckeylen = seskey->keylen + 1; /* Return the session key in case we allocated it. */ *r_seskey = seskey; seskey = NULL; @@ -332,7 +388,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) { DEK *dek = NULL; - rc = encrypt_seskey (cfx.dek, &dek, &enckey, &enckeylen); + rc = encrypt_seskey (cfx.dek, aead_algo, &dek, &enckey, &enckeylen); if (rc) { xfree (cfx.dek); @@ -346,14 +402,16 @@ encrypt_simple (const char *filename, int mode, int use_seskey) cfx.dek = dek; } - if (opt.verbose) - log_info(_("using cipher %s\n"), - openpgp_cipher_algo_name (cfx.dek->algo)); - if (aead_algo) cfx.dek->use_aead = aead_algo; else cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); + + if (opt.verbose) + log_info(_("using cipher %s.%s\n"), + openpgp_cipher_algo_name (cfx.dek->algo), + cfx.dek->use_aead? openpgp_aead_algo_name (cfx.dek->use_aead) + /**/ : "CFB"); } if (do_compress @@ -385,8 +443,9 @@ encrypt_simple (const char *filename, int mode, int use_seskey) { /* Fixme: This is quite similar to write_symkey_enc. */ PKT_symkey_enc *enc = xmalloc_clear (sizeof *enc + enckeylen); - enc->version = 4; + enc->version = cfx.dek->use_aead ? 5 : 4; enc->cipher_algo = cfx.dek->algo; + enc->aead_algo = cfx.dek->use_aead; enc->s2k = *s2k; if (enckeylen) { @@ -535,8 +594,8 @@ setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek) static int -write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, - iobuf_t out) +write_symkey_enc (STRING2KEY *symkey_s2k, aead_algo_t aead_algo, + DEK *symkey_dek, DEK *dek, iobuf_t out) { int rc; void *enckey; @@ -544,7 +603,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, PKT_symkey_enc *enc; PACKET pkt; - rc = encrypt_seskey (symkey_dek, &dek, &enckey, &enckeylen); + rc = encrypt_seskey (symkey_dek, aead_algo, &dek, &enckey, &enckeylen); if (rc) return rc; enc = xtrycalloc (1, sizeof (PKT_symkey_enc) + enckeylen); @@ -555,8 +614,9 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, return rc; } - enc->version = 4; + enc->version = aead_algo? 5 : 4; enc->cipher_algo = opt.s2k_cipher_algo; + enc->aead_algo = aead_algo; enc->s2k = *symkey_s2k; enc->seskeylen = enckeylen; memcpy (enc->seskey, enckey, enckeylen); @@ -813,10 +873,11 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, goto leave; /* We put the passphrase (if any) after any public keys as this - seems to be the most useful on the recipient side - there is no - point in prompting a user for a passphrase if they have the - secret key needed to decrypt. */ - if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out))) + * seems to be the most useful on the recipient side - there is no + * point in prompting a user for a passphrase if they have the + * secret key needed to decrypt. */ + if (use_symkey && (rc = write_symkey_enc (symkey_s2k, cfx.dek->use_aead, + symkey_dek, cfx.dek, out))) goto leave; if (!opt.no_literal) @@ -1014,9 +1075,9 @@ encrypt_filter (void *opaque, int control, if(efx->symkey_s2k && efx->symkey_dek) { - rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek, - efx->cfx.dek,a); - if(rc) + rc = write_symkey_enc (efx->symkey_s2k, efx->cfx.dek->use_aead, + efx->symkey_dek, efx->cfx.dek, a); + if (rc) return rc; } @@ -1084,9 +1145,11 @@ write_pubkey_enc (ctrl_t ctrl, if ( opt.verbose ) { char *ustr = get_user_id_string_native (ctrl, enc->keyid); - log_info (_("%s/%s encrypted for: \"%s\"\n"), + log_info (_("%s/%s.%s encrypted for: \"%s\"\n"), openpgp_pk_algo_name (enc->pubkey_algo), openpgp_cipher_algo_name (dek->algo), + dek->use_aead? openpgp_aead_algo_name (dek->use_aead) + /**/ : "CFB", ustr ); xfree (ustr); } diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index f22c7c2..094bc76 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -2284,7 +2284,7 @@ sk_esk (const char *option, int argc, char *argv[], void *cookie) /* Now encrypt the session key (or rather, the algorithm used to encrypt the SKESK plus the session key) using ENCKEY. */ - err = encrypt_seskey (&s2kdek, &sesdekp, + err = encrypt_seskey (&s2kdek, 0, &sesdekp, (void**)&ske->seskey, (size_t *)&ske->seskeylen); if (err) log_fatal ("encrypt_seskey failed: %s\n", gpg_strerror (err)); diff --git a/g10/import.c b/g10/import.c index 71e3955..ed679d5 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1113,6 +1113,24 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock) problem=1; } } + else if(prefs->type==PREFTYPE_AEAD) + { + if (openpgp_aead_test_algo (prefs->value)) + { + /* FIXME: The test below is wrong. We should + * check if ...algo_name yields a "?" and + * only in that case use NUM. */ + const char *algo = + (openpgp_aead_test_algo (prefs->value) + ? num + : openpgp_aead_algo_name (prefs->value)); + if(!problem) + check_prefs_warning(pk); + log_info(_(" \"%s\": preference for AEAD" + " algorithm %s\n"), user, algo); + problem=1; + } + } else if(prefs->type==PREFTYPE_HASH) { if(openpgp_md_test_algo(prefs->value)) @@ -2255,6 +2273,7 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats, { char countbuf[35]; + /* FIXME: Support AEAD */ /* Note that the IVLEN may be zero if we are working on a dummy key. We can't express that in an S-expression and thus we send dummy data for the IV. */ diff --git a/g10/keyedit.c b/g10/keyedit.c index 81344eb..3ae96a3 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3064,6 +3064,23 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose) tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES)); } tty_printf ("\n "); + tty_printf (_("AEAD: ")); + for (i = any = 0; prefs[i].type; i++) + { + if (prefs[i].type == PREFTYPE_AEAD) + { + if (any) + tty_printf (", "); + any = 1; + /* We don't want to display strings for experimental algos */ + if (!openpgp_aead_test_algo (prefs[i].value) + && prefs[i].value < 100) + tty_printf ("%s", openpgp_aead_algo_name (prefs[i].value)); + else + tty_printf ("[%d]", prefs[i].value); + } + } + tty_printf ("\n "); tty_printf (_("Digest: ")); for (i = any = 0; prefs[i].type; i++) { @@ -3172,6 +3189,7 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose) for (i = 0; prefs[i].type; i++) { tty_printf (" %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' : + prefs[i].type == PREFTYPE_AEAD ? 'A' : prefs[i].type == PREFTYPE_HASH ? 'H' : prefs[i].type == PREFTYPE_ZIP ? 'Z' : '?', prefs[i].value); diff --git a/g10/main.h b/g10/main.h index 96899ac..a02c574 100644 --- a/g10/main.h +++ b/g10/main.h @@ -235,7 +235,7 @@ void display_online_help( const char *keyword ); /*-- encode.c --*/ int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); -gpg_error_t encrypt_seskey (DEK *dek, DEK **r_seskey, +gpg_error_t encrypt_seskey (DEK *dek, aead_algo_t aead_algo, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen); aead_algo_t use_aead (pk_list_t pk_list, int algo); int use_mdc (pk_list_t pk_list,int algo); diff --git a/g10/mainproc.c b/g10/mainproc.c index 92da982..d1d44d7 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -245,46 +245,102 @@ add_signature (CTX c, PACKET *pkt) return 1; } -static int +static gpg_error_t symkey_decrypt_seskey (DEK *dek, byte *seskey, size_t slen) { + gpg_error_t err; gcry_cipher_hd_t hd; + unsigned int noncelen, keylen; + enum gcry_cipher_modes ciphermode; + byte ad[4]; + + if (dek->use_aead) + { + err = openpgp_aead_algo_info (dek->use_aead, &ciphermode, &noncelen); + if (err) + return err; + } + else + { + ciphermode = GCRY_CIPHER_MODE_CFB; + noncelen = 0; + } - if(slen < 17 || slen > 33) + /* Check that the session key has a size of 16 to 32 bytes. */ + if ((dek->use_aead && (slen < (noncelen + 16 + 16) + || slen > (noncelen + 32 + 16))) + || (!dek->use_aead && (slen < 17 || slen > 33))) { log_error ( _("weird size for an encrypted session key (%d)\n"), (int)slen); - return GPG_ERR_BAD_KEY; + return gpg_error (GPG_ERR_BAD_KEY); } - if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) - BUG (); - if (gcry_cipher_setkey ( hd, dek->key, dek->keylen )) - BUG (); - gcry_cipher_setiv ( hd, NULL, 0 ); - gcry_cipher_decrypt ( hd, seskey, slen, NULL, 0 ); - gcry_cipher_close ( hd ); - - /* Now we replace the dek components with the real session key to - decrypt the contents of the sequencing packet. */ - - dek->keylen=slen-1; - dek->algo=seskey[0]; + err = openpgp_cipher_open (&hd, dek->algo, ciphermode, GCRY_CIPHER_SECURE); + if (!err) + err = gcry_cipher_setkey (hd, dek->key, dek->keylen); + if (!err) + err = gcry_cipher_setiv (hd, noncelen? seskey : NULL, noncelen); + if (err) + goto leave; - if(dek->keylen > DIM(dek->key)) - BUG (); - - memcpy(dek->key, seskey + 1, dek->keylen); + if (dek->use_aead) + { + byte ad[4]; + + ad[0] = (0xc0 | PKT_SYMKEY_ENC); + ad[1] = 5; + ad[2] = dek->algo; + ad[3] = dek->use_aead; + err = gcry_cipher_authenticate (hd, ad, 4); + if (err) + goto leave; + gcry_cipher_final (hd); + keylen = slen - noncelen - 16; + err = gcry_cipher_decrypt (hd, seskey+noncelen, keylen, NULL, 0); + if (err) + goto leave; + err = gcry_cipher_checktag (hd, seskey+noncelen+keylen, 16); + if (err) + goto leave; + /* Now we replace the dek components with the real session key to + * decrypt the contents of the sequencing packet. */ + if (keylen > DIM(dek->key)) + { + err = gpg_error (GPG_ERR_TOO_LARGE); + goto leave; + } + dek->keylen = keylen; + memcpy (dek->key, seskey + noncelen, dek->keylen); + } + else + { + gcry_cipher_decrypt (hd, seskey, slen, NULL, 0 ); + /* Now we replace the dek components with the real session key to + * decrypt the contents of the sequencing packet. */ + keylen = slen-1; + if (keylen > DIM(dek->key)) + { + err = gpg_error (GPG_ERR_TOO_LARGE); + goto leave; + } + dek->algo = seskey[0]; + dek->keylen = keylen; + memcpy (dek->key, seskey + 1, dek->keylen); + } /*log_hexdump( "thekey", dek->key, dek->keylen );*/ - return 0; + leave: + gcry_cipher_close (hd); + return err; } static void proc_symkey_enc (CTX c, PACKET *pkt) { + gpg_error_t err; PKT_symkey_enc *enc; enc = pkt->pkt.symkey_enc; @@ -294,19 +350,21 @@ proc_symkey_enc (CTX c, PACKET *pkt) { int algo = enc->cipher_algo; const char *s = openpgp_cipher_algo_name (algo); + const char *a = (enc->aead_algo ? openpgp_aead_algo_name (enc->aead_algo) + /**/ : "CFB"); if (!openpgp_cipher_test_algo (algo)) { if (!opt.quiet) { if (enc->seskeylen) - log_info (_("%s encrypted session key\n"), s ); + log_info (_("%s.%s encrypted session key\n"), s, a ); else - log_info (_("%s encrypted data\n"), s ); + log_info (_("%s.%s encrypted data\n"), s, a ); } } else - log_error (_("encrypted with unknown algorithm %d\n"), algo); + log_error (_("encrypted with unknown algorithm %d.%s\n"), algo, a); if (openpgp_md_test_algo (enc->s2k.hash_algo)) { @@ -334,6 +392,7 @@ proc_symkey_enc (CTX c, PACKET *pkt) if (c->dek) { c->dek->symmetric = 1; + c->dek->use_aead = enc->aead_algo; /* FIXME: This doesn't work perfectly if a symmetric key comes before a public key in the message - if the @@ -344,9 +403,16 @@ proc_symkey_enc (CTX c, PACKET *pkt) come later. */ if (enc->seskeylen) { - if (symkey_decrypt_seskey (c->dek, - enc->seskey, enc->seskeylen)) + err = symkey_decrypt_seskey (c->dek, + enc->seskey, enc->seskeylen); + if (err) { + log_info ("decryption of the symmetrically encrypted" + " session key failed: %s\n", + gpg_strerror (err)); + if (gpg_err_code (err) != GPG_ERR_BAD_KEY) + log_fatal ("process terminated to be bug compatible" + " with GnuPG <= 2.2\n"); xfree (c->dek); c->dek = NULL; } diff --git a/g10/packet.h b/g10/packet.h index 4d15574..4f4569f 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -94,12 +94,14 @@ typedef struct /* A symmetric-key encrypted session key packet as defined in RFC 4880, Section 5.3. All fields are serialized. */ typedef struct { - /* RFC 4880: this must be 4. */ + /* We support version 4 (rfc4880) and 5 (rfc4880bis). */ byte version; - /* The cipher algorithm used to encrypt the session key. (This may - be different from the algorithm that is used to encrypt the SED - packet.) */ + /* The cipher algorithm used to encrypt the session key. Note that + * this may be different from the algorithm that is used to encrypt + * bulk data. */ byte cipher_algo; + /* The AEAD algorithm or 0 for CFB encryption. */ + byte aead_algo; /* The string-to-key specifier. */ STRING2KEY s2k; /* The length of SESKEY in bytes or 0 if this packet does not @@ -107,7 +109,8 @@ typedef struct { S2K function on the password is the session key. See RFC 4880, Section 5.3.) */ byte seskeylen; - /* The session key as encrypted by the S2K specifier. */ + /* The session key as encrypted by the S2K specifier. For AEAD this + * includes the nonce and the authentication tag. */ byte seskey[1]; } PKT_symkey_enc; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index de51770..5c6d364 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1105,7 +1105,7 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, { PKT_symkey_enc *k; int rc = 0; - int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen; + int i, version, s2kmode, cipher_algo, aead_algo, hash_algo, seskeylen, minlen; if (pktlen < 4) { @@ -1117,7 +1117,11 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } version = iobuf_get_noeof (inp); pktlen--; - if (version != 4) + if (version == 4) + ; + else if (version == 5) + ; + else { log_error ("packet(%d) with unknown version %d\n", pkttype, version); if (list_mode) @@ -1135,6 +1139,13 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } cipher_algo = iobuf_get_noeof (inp); pktlen--; + if (version == 5) + { + aead_algo = iobuf_get_noeof (inp); + pktlen--; + } + else + aead_algo = 0; s2kmode = iobuf_get_noeof (inp); pktlen--; hash_algo = iobuf_get_noeof (inp); @@ -1169,6 +1180,7 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, + seskeylen - 1); k->version = version; k->cipher_algo = cipher_algo; + k->aead_algo = aead_algo; k->s2k.mode = s2kmode; k->s2k.hash_algo = hash_algo; if (s2kmode == 1 || s2kmode == 3) @@ -1199,10 +1211,20 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, if (list_mode) { es_fprintf (listfp, - ":symkey enc packet: version %d, cipher %d, s2k %d, hash %d", - version, cipher_algo, s2kmode, hash_algo); + ":symkey enc packet: version %d, cipher %d, aead %d," + " s2k %d, hash %d", + version, cipher_algo, aead_algo, s2kmode, hash_algo); if (seskeylen) - es_fprintf (listfp, ", seskey %d bits", (seskeylen - 1) * 8); + { + /* To compute the size of the session key we need to know + * the size of the AEAD nonce which we may not know. Thus + * we show only the seize of the entire encrypted session + * key. */ + if (aead_algo) + es_fprintf (listfp, ", encrypted seskey %d bytes", seskeylen); + else + es_fprintf (listfp, ", seskey %d bits", (seskeylen - 1) * 8); + } es_fprintf (listfp, "\n"); if (s2kmode == 1 || s2kmode == 3) { diff --git a/g10/sign.c b/g10/sign.c index 7045e8c..df71ccc 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1326,9 +1326,6 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) s2k->hash_algo = S2K_DIGEST_ALGO; algo = default_cipher_algo(); - if (!opt.quiet || !opt.batch) - log_info (_("%s encryption will be used\n"), - openpgp_cipher_algo_name (algo) ); cfx.dek = passphrase_to_dek (algo, s2k, 1, 1, NULL, &canceled); if (!cfx.dek || !cfx.dek->keylen) { @@ -1341,6 +1338,12 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) if (!cfx.dek->use_aead) cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); + if (!opt.quiet || !opt.batch) + log_info (_("%s.%s encryption will be used\n"), + openpgp_cipher_algo_name (algo), + cfx.dek->use_aead? openpgp_aead_algo_name (cfx.dek->use_aead) + /**/ : "CFB"); + /* now create the outfile */ rc = open_outfile (-1, fname, opt.armor? 1:0, 0, &out); if (rc) commit da3015e3c05030fe709c8f922486e73d06d1d16a Author: Werner Koch Date: Mon Jan 22 16:23:02 2018 +0100 gpg: Unify AEAD parameter retrieval. * g10/pkclist.c (select_aead_from_pklist): Return the AEAD_algo. * g10/encrypt.c (use_aead): Return the AEAD algo. (encrypt_simple): Adjust for this change. (encrypt_crypt): Ditto. (encrypt_filter): Ditto. * g10/sign.c (sign_symencrypt_file): Ditto. * g10/misc.c (MY_GCRY_CIPHER_MODE_EAX): New. (openpgp_aead_algo_info): New. * g10/cipher-aead.c (MY_GCRY_CIPHER_MODE_EAX): Remove. (write_header): Use new fucntion. * g10/decrypt-data.c (MY_GCRY_CIPHER_MODE_EAX): Remove. (decrypt_data): Use new function. Also allow for chunkbytes other than 10. -- Note that other chunk bytes than 10 and in particular 0 (64 byte chunks) have not yet been tested. Signed-off-by: Werner Koch diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index 1d72634..637bd71 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -33,10 +33,6 @@ #include "options.h" #include "main.h" -/* FIXME: Libgcrypt 1.9 will support EAX. Until we kame this a - * requirement we hardwire the enum used for EAX. */ -#define MY_GCRY_CIPHER_MODE_EAX 14 - /* The size of the buffer we allocate to encrypt the data. This must * be a multiple of the OCB blocksize (16 byte). */ @@ -149,23 +145,9 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) if (blocksize != 16 ) log_fatal ("unsupported blocksize %u for AEAD\n", blocksize); - switch (cfx->dek->use_aead) - { - case AEAD_ALGO_OCB: - ciphermode = GCRY_CIPHER_MODE_OCB; - startivlen = 15; - break; - - case AEAD_ALGO_EAX: - ciphermode = MY_GCRY_CIPHER_MODE_EAX; - startivlen = 16; - break; - - default: - log_error ("unsupported AEAD algo %d\n", cfx->dek->use_aead); - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - goto leave; - } + err = openpgp_aead_algo_info (cfx->dek->use_aead, &ciphermode, &startivlen); + if (err) + goto leave; cfx->chunkbyte = 10; cfx->chunksize = (uint64_t)1 << (cfx->chunkbyte + 6); diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 79e2554..7ed0bf0 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -31,10 +31,6 @@ #include "../common/status.h" #include "../common/compliance.h" -/* FIXME: Libgcrypt 1.9 will support EAX. Until we kame this a - * requirement we hardwire the enum used for EAX. */ -#define MY_GCRY_CIPHER_MODE_EAX 14 - static int aead_decode_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); @@ -274,28 +270,15 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) goto leave; } - switch (ed->aead_algo) - { - case AEAD_ALGO_OCB: - startivlen = 15; - ciphermode = GCRY_CIPHER_MODE_OCB; - break; - case AEAD_ALGO_EAX: - startivlen = 16; - ciphermode = MY_GCRY_CIPHER_MODE_EAX; - break; - default: - log_error ("unknown AEAD algo %d\n", ed->aead_algo); - rc = gpg_error (GPG_ERR_INV_CIPHER_MODE); - goto leave; - } + rc = openpgp_aead_algo_info (ed->aead_algo, &ciphermode, &startivlen); + if (rc) + goto leave; log_assert (startivlen <= sizeof dfx->startiv); - if (ed->chunkbyte != 10) + if (ed->chunkbyte > 56) { - /* FIXME */ - log_error ("unsupported chunkbyte %u\n", ed->chunkbyte); - rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + log_error ("invalid AEAD chunkbyte %u\n", ed->chunkbyte); + rc = gpg_error (GPG_ERR_INV_PACKET); goto leave; } diff --git a/g10/encrypt.c b/g10/encrypt.c index ab745ce..4cc4b1a 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -139,8 +139,9 @@ encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen) } -/* Return true if we shall use AEAD mode. */ -int +/* Return the AEAD algo if we shall use AEAD mode. Returns 0 if AEAD + * shall not be used. */ +aead_algo_t use_aead (pk_list_t pk_list, int algo) { int can_use; @@ -168,7 +169,7 @@ use_aead (pk_list_t pk_list, int algo) openpgp_cipher_algo_name (algo)); return 0; } - return 1; + return default_aead_algo (); } /* AEAD does only work with 128 bit cipher blocklength. */ @@ -176,10 +177,7 @@ use_aead (pk_list_t pk_list, int algo) return 0; /* If all keys support AEAD we can use it. */ - if (select_aead_from_pklist (pk_list)) - return 1; - - return 0; /* No AEAD. */ + return select_aead_from_pklist (pk_list); } @@ -328,7 +326,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) } /* See whether we want to use AEAD. */ - aead_algo = use_aead (NULL, cfx.dek->algo)? default_aead_algo () : 0; + aead_algo = use_aead (NULL, cfx.dek->algo); if ( use_seskey ) { @@ -784,9 +782,8 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, gnupg_status_compliance_flag (CO_DE_VS), NULL); - if (use_aead (pk_list, cfx.dek->algo)) - cfx.dek->use_aead = 1; - else + cfx.dek->use_aead = use_aead (pk_list, cfx.dek->algo); + if (!cfx.dek->use_aead) cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo); /* Only do the is-file-already-compressed check if we are using a @@ -1002,9 +999,8 @@ encrypt_filter (void *opaque, int control, efx->cfx.dek->algo = opt.def_cipher_algo; } - if (use_aead (efx->pk_list, efx->cfx.dek->algo)) - efx->cfx.dek->use_aead = 1; - else + efx->cfx.dek->use_aead = use_aead (efx->pk_list, efx->cfx.dek->algo); + if (!efx->cfx.dek->use_aead) efx->cfx.dek->use_mdc = !!use_mdc (efx->pk_list,efx->cfx.dek->algo); make_session_key ( efx->cfx.dek ); diff --git a/g10/keydb.h b/g10/keydb.h index 9f6064b..f2ea8a7 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -232,7 +232,7 @@ int algo_available( preftype_t preftype, int algo, int select_algo_from_prefs( PK_LIST pk_list, int preftype, int request, const union pref_hint *hint); int select_mdc_from_pklist (PK_LIST pk_list); -int select_aead_from_pklist (pk_list_t pk_list); +aead_algo_t select_aead_from_pklist (pk_list_t pk_list); void warn_missing_mdc_from_pklist (PK_LIST pk_list); void warn_missing_aes_from_pklist (PK_LIST pk_list); diff --git a/g10/main.h b/g10/main.h index 509126c..96899ac 100644 --- a/g10/main.h +++ b/g10/main.h @@ -127,6 +127,9 @@ const char *openpgp_cipher_algo_name (cipher_algo_t algo); gpg_error_t openpgp_aead_test_algo (aead_algo_t algo); const char *openpgp_aead_algo_name (aead_algo_t algo); +gpg_error_t openpgp_aead_algo_info (aead_algo_t algo, + enum gcry_cipher_modes *r_mode, + unsigned int *r_noncelen); pubkey_algo_t map_pk_gcry_to_openpgp (enum gcry_pk_algos algo); int openpgp_pk_test_algo (pubkey_algo_t algo); @@ -234,7 +237,7 @@ void display_online_help( const char *keyword ); int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); gpg_error_t encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen); -int use_aead (pk_list_t pk_list, int algo); +aead_algo_t use_aead (pk_list_t pk_list, int algo); int use_mdc (pk_list_t pk_list,int algo); int encrypt_symmetric (const char *filename ); int encrypt_store (const char *filename ); diff --git a/g10/misc.c b/g10/misc.c index f7ac3c7..36d3bdc 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -70,6 +70,11 @@ #include "../common/zb32.h" +/* FIXME: Libgcrypt 1.9 will support EAX. Until we kame this a + * requirement we hardwire the enum used for EAX. */ +#define MY_GCRY_CIPHER_MODE_EAX 14 + + #ifdef ENABLE_SELINUX_HACKS /* A object and a global variable to keep track of files marked as secured. */ @@ -616,6 +621,34 @@ openpgp_aead_algo_name (aead_algo_t algo) } +/* Return information for the AEAD algorithm ALGO. The corresponding + * Libgcrypt ciphermode is stored at R_MODE and the required number of + * octets for the nonce at R_NONCELEN. On error and error code is + * returned. Note that the taglen is always 128 bits. */ +gpg_error_t +openpgp_aead_algo_info (aead_algo_t algo, enum gcry_cipher_modes *r_mode, + unsigned int *r_noncelen) +{ + switch (algo) + { + case AEAD_ALGO_OCB: + *r_mode = GCRY_CIPHER_MODE_OCB; + *r_noncelen = 15; + break; + + case AEAD_ALGO_EAX: + *r_mode = MY_GCRY_CIPHER_MODE_EAX; + *r_noncelen = 16; + break; + + default: + log_error ("unsupported AEAD algo %d\n", algo); + return gpg_error (GPG_ERR_INV_CIPHER_MODE); + } + return 0; +} + + /* Return 0 if ALGO is a supported OpenPGP public key algorithm. */ int openpgp_pk_test_algo (pubkey_algo_t algo) diff --git a/g10/pkclist.c b/g10/pkclist.c index b85efa4..6ec5537 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -1652,8 +1652,9 @@ select_mdc_from_pklist (PK_LIST pk_list) /* Select the AEAD flag from the pk_list. We can only use AEAD if all - * recipients support this feature. Returns true if AEAD can be used. */ -int + * recipients support this feature. Returns the AEAD to be used or 0 + * if AEAD shall not be used. */ +aead_algo_t select_aead_from_pklist (PK_LIST pk_list) { pk_list_t pkr; @@ -1672,7 +1673,7 @@ select_aead_from_pklist (PK_LIST pk_list) return 0; /* At least one recipient does not support it. */ } - return 1; /* Can be used. */ + return default_aead_algo (); /* Yes, AEAD can be used. */ } diff --git a/g10/sign.c b/g10/sign.c index 051ab59..7045e8c 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1337,9 +1337,8 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) goto leave; } - if (use_aead (NULL, cfx.dek->algo)) - cfx.dek->use_aead = 1; - else + cfx.dek->use_aead = use_aead (NULL, cfx.dek->algo); + if (!cfx.dek->use_aead) cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo); /* now create the outfile */ ----------------------------------------------------------------------- Summary of changes: g10/build-packet.c | 36 +++++------ g10/cipher-aead.c | 24 +------- g10/decrypt-data.c | 35 +++-------- g10/encrypt.c | 175 +++++++++++++++++++++++++++++++++++------------------ g10/getkey.c | 14 ++++- g10/gpgcompose.c | 2 +- g10/import.c | 19 ++++++ g10/keydb.h | 2 +- g10/keyedit.c | 18 ++++++ g10/main.h | 7 ++- g10/mainproc.c | 126 ++++++++++++++++++++++++++++++-------- g10/misc.c | 33 ++++++++++ g10/packet.h | 13 ++-- g10/parse-packet.c | 32 ++++++++-- g10/pkclist.c | 7 ++- g10/sign.c | 14 +++-- 16 files changed, 383 insertions(+), 174 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 24 13:58:18 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 24 Jan 2018 13:58:18 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.3-126-gff1bdc2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via ff1bdc23d9f1693c1add7c1fe8d218b7bf743e31 (commit) via 83a15fa88e91d277811b6d030c4aa40c4fb3e6ad (commit) via f3ef8b0dcaede1c85da0dff8eeceda6a994f0b28 (commit) from 112e02ee89b78369c1c50e672873e726cbfeb994 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ff1bdc23d9f1693c1add7c1fe8d218b7bf743e31 Author: Werner Koch Date: Wed Jan 24 13:45:05 2018 +0100 gpg: Fix AEAD encryption for chunk sizes other than 64 KiB. * g10/cipher-aead.c (do_flush): Init ERR. Fix remaining chunklen computation. (do_free): Add dummy encryption. Close the cipher handle. * g10/decrypt-data.c (aead_underflow): Rewrite. -- Until we have integrated test into the test suite extensive tests can also be done with a script like this: --8<---------------cut here---------------start------------->8--- #!/bin/sh set -e GPG="../g10/gpg --rfc4880bis --pinentry-mode=loopback" GPG="$GPG --passphrase abc --batch" MKTDATA="$HOME/b/gnupg-2.0/tools/mk-tdata" for chunksize in 6 7 12 13 14 30; do for count in $(seq 1 200) $(seq 8100 8200) \ $(seq 16350 16400) $(seq 20000 20100); do if [ ! -f "testfile-$count" ]; then $MKTDATA $count >"testfile-$count" fi echo "testing chunk size 2^$chunksize with $count bytes" $GPG --force-aead --aead-algo ocb --s2k-mode 0 --cipher AES -v -z 0 \ -c --chunk-size $chunksize \ <"testfile-$count" >"testfile-$count.gpg" 2>/dev/null $GPG -vd <"testfile-$count.gpg" >"testfile-$count.out" 2>/dev/null if ! cmp "testfile-$count" "testfile-$count.out"; then echo "FAILED comparing count $count" >&2 exit 1 fi done done echo All good --8<---------------cut here---------------end--------------->8--- Signed-off-by: Werner Koch diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index 9cb57bd..573bb43 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -271,7 +271,7 @@ write_final_chunk (cipher_filter_context_t *cfx, iobuf_t a) static gpg_error_t do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) { - gpg_error_t err; + gpg_error_t err = 0; int newchunk = 0; size_t n; @@ -285,9 +285,9 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) else n = cfx->bufsize - cfx->buflen; - if (cfx->chunklen + n >= cfx->chunksize) + if (cfx->chunklen + cfx->buflen + n >= cfx->chunksize) { - size_t n1 = cfx->chunksize - cfx->chunklen; + size_t n1 = cfx->chunksize - (cfx->chunklen + cfx->buflen); newchunk = 1; if (DBG_FILTER) log_debug ("chunksize %ju reached;" @@ -305,8 +305,8 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) if (cfx->buflen == cfx->bufsize || newchunk) { if (DBG_FILTER) - log_debug ("encrypting: buflen=%zu %s %p\n", - cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd); + log_debug ("encrypting: buflen=%zu %s n=%zu\n", + cfx->buflen, newchunk?"(newchunk)":"", n); if (newchunk) gcry_cipher_final (cfx->cipher_hd); if (!DBG_FILTER) @@ -372,6 +372,9 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) { gpg_error_t err = 0; + if (DBG_FILTER) + log_debug ("do_free: buflen=%zu\n", cfx->buflen); + /* FIXME: Check what happens if we just wrote the last chunk and no * more bytes were to encrypt. We should then not call finalize and * write the auth tag again, right? May this at all happen? */ @@ -394,6 +397,8 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) cfx->chunklen += cfx->buflen; cfx->total += cfx->buflen; } + else /* Dummy encryption. */ + gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, 0, NULL, 0); /* Get and write the authentication tag. */ if (DBG_FILTER) @@ -411,8 +416,8 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) leave: xfree (cfx->buffer); cfx->buffer = NULL; - /* gcry_cipher_close (cfx->cipher_hd); */ - /* cfx->cipher_hd = NULL; */ + gcry_cipher_close (cfx->cipher_hd); + cfx->cipher_hd = NULL; return err; } diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index fc72472..afdedcb 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -56,8 +56,8 @@ struct decode_filter_context_s /* The start IV for AEAD encryption. */ byte startiv[16]; - /* The holdback buffer and its used length. For AEAD we need at - * least 32+1 byte for MDC 22 bytes are required. */ + /* The holdback buffer and its used length. For AEAD we need 32+1 + * bytes but we use 48 byte. For MDC we need 22 bytes. */ char holdback[48]; unsigned int holdbacklen; @@ -536,262 +536,277 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) static gpg_error_t aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) { - const size_t size = *ret_len; /* The initial length of BUF. */ + const size_t size = *ret_len; /* The allocated size of BUF. */ gpg_error_t err; - size_t n; /* Finally the number of decrypted bytes in BUF. */ + size_t totallen = 0; /* The number of bytes to return on success or EOF. */ + size_t off = 0; /* The offset into the buffer. */ + size_t len; /* The current number of bytes in BUF+OFF. */ int c; - log_assert (size > 64); /* Our code requires at least this size. */ + log_assert (size > 48); /* Our code requires at least this size. */ - /* Get at least 32 bytes and put it ahead in the buffer. */ + /* Copy the rest from the last call of this function into BUF. */ + len = dfx->holdbacklen; + dfx->holdbacklen = 0; + memcpy (buf, dfx->holdback, len); + + if (DBG_FILTER) + log_debug ("aead_underflow: size=%zu len=%zu%s\n", + size, len, dfx->eof_seen? " eof":""); + + /* Read and fill up BUF. We need to watchout for an EOF so that we + * can detect the last chunk which is commonly shorter than the + * chunksize. After the last data byte from the last chunk 32 more + * bytes are expected for the last chunk's tag and the following + * final chunk's tag. To detect the EOF we need to read at least + * one further byte; however we try to ready 16 extra bytes to avoid + * singel byte reads in some lower layers. The outcome is that we + * have up to 48 extra extra octets which we will later put into the + * holdback buffer for the next invocation (which handles the EOF + * case). */ if (dfx->partial) { - for (n=32; n < 64; n++) + for (; len < size; len++ ) { if ((c = iobuf_get (a)) == -1) - break; - buf[n] = c; + { + dfx->eof_seen = 1; /* Normal EOF. */ + break; + } + buf[len] = c; } } else { - for (n=32; n < 64 && dfx->length; n++, dfx->length--) + for (; len < size && dfx->length; len++, dfx->length--) { - if ((c = iobuf_get (a)) == -1) - break; /* Premature EOF. */ - buf[n] = c; + c = iobuf_get (a); + if (c == -1) + { + dfx->eof_seen = 3; /* Premature EOF. */ + break; + } + buf[len] = c; } + if (!dfx->length) + dfx->eof_seen = 1; /* Normal EOF. */ } - if (n == 64) + if (len < 32) { - /* We got 32 bytes from A which are good for the last chunk's - * auth tag and the final chunk's auth tag. On the first time - * we don't have anything in the holdback buffer and thus we move - * those 32 bytes to the start of the buffer. All further calls - * will copy the 32 bytes from the holdback buffer to the start of the - * buffer. */ - if (!dfx->holdbacklen) - { - memcpy (buf, buf+32, 32); - n = 32; /* Continue at this position. */ - } - else + /* Not enough data for the last two tags. */ + err = gpg_error (GPG_ERR_TRUNCATED); + goto leave; + } + if (dfx->eof_seen) + { + /* If have seen an EOF we copy only the last two auth tags into + * the holdback buffer. */ + dfx->holdbacklen = 32; + memcpy (dfx->holdback, buf+len-32, 32); + len -= 32; + } + else + { + /* If have not seen an EOF we copy the entire extra 48 bytes + * into the holdback buffer for processing at the next call of + * this function. */ + dfx->holdbacklen = len > 48? 48 : len; + memcpy (dfx->holdback, buf+len-dfx->holdbacklen, dfx->holdbacklen); + len -= dfx->holdbacklen; + } + /* log_printhex (dfx->holdback, dfx->holdbacklen, "holdback:"); */ + + /* Decrypt the buffer. This requires a loop because a chunk may end + * within the buffer. */ + if (DBG_FILTER) + log_debug ("decrypt loop: chunklen=%ju total=%ju size=%zu len=%zu%s\n", + (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, size, len, + dfx->eof_seen? " eof":""); + + while (len && dfx->chunklen + len >= dfx->chunksize) + { + size_t n = dfx->chunksize - dfx->chunklen; + byte tagbuf[16]; + + if (DBG_FILTER) + log_debug ("chunksize will be reached: n=%zu\n", n); + /* log_printhex (buf, n, "ciph:"); */ + gcry_cipher_final (dfx->cipher_hd); + err = gcry_cipher_decrypt (dfx->cipher_hd, buf+off, n, NULL, 0); + if (err) { - memcpy (buf, dfx->holdback, 32); + log_error ("gcry_cipher_decrypt failed (1): %s\n", + gpg_strerror (err)); + goto leave; } + /* log_printhex (buf, n, "plai:"); */ + totallen += n; + dfx->chunklen += n; + dfx->total += n; + off += n; + len -= n; - /* Now fill up the provided buffer. */ - if (dfx->partial) + if (DBG_FILTER) + log_debug ("bytes left: %zu at off=%zu\n", len, off); + + /* Check the tag. */ + if (len < 16) { - for (; n < size; n++ ) + /* The tag is not entirely in the buffer. Read the rest of + * the tag from the holdback buffer. The shift the holdback + * buffer and fill it up again. */ + memcpy (tagbuf, buf+off, len); + memcpy (tagbuf + len, dfx->holdback, 16 - len); + dfx->holdbacklen -= 16-len; + memmove (dfx->holdback, dfx->holdback + (16-len), dfx->holdbacklen); + + len = dfx->holdbacklen; + if (dfx->partial) { - if ((c = iobuf_get (a)) == -1) + for (; len < 48; len++ ) { - dfx->eof_seen = 1; /* Normal EOF. */ - break; + if ((c = iobuf_get (a)) == -1) + { + dfx->eof_seen = 1; /* Normal EOF. */ + break; + } + dfx->holdback[len] = c; } - buf[n] = c; } - } - else - { - for (; n < size && dfx->length; n++, dfx->length--) + else { - c = iobuf_get (a); - if (c == -1) + for (; len < 48 && dfx->length; len++, dfx->length--) { - dfx->eof_seen = 3; /* Premature EOF. */ - break; + c = iobuf_get (a); + if (c == -1) + { + dfx->eof_seen = 3; /* Premature EOF. */ + break; + } + dfx->holdback[len] = c; } - buf[n] = c; + if (!dfx->length) + dfx->eof_seen = 1; /* Normal EOF. */ + } + if (len < 32) + { + /* Not enough data for the last two tags. */ + err = gpg_error (GPG_ERR_TRUNCATED); + goto leave; } - if (!dfx->length) - dfx->eof_seen = 1; /* Normal EOF. */ + dfx->holdbacklen = len; + /* log_printhex (dfx->holdback, dfx->holdbacklen, "holdback:"); */ + len = 0; + } + else /* We already have the full tag. */ + { + memcpy (tagbuf, buf+off, 16); + /* Remove that tag from the output. */ + memmove (buf + off, buf + off + 16, len - 16); + len -= 16; + } + if (DBG_CRYPTO) + log_printhex (tagbuf, 16, "tag:"); + err = gcry_cipher_checktag (dfx->cipher_hd, tagbuf, 16); + if (err) + { + if (DBG_FILTER) + log_debug ("gcry_cipher_checktag failed (1): %s\n", + gpg_strerror (err)); + goto leave; } - /* Move the trailing 32 bytes back to the holdback buffer. We - * got at least 64 bytes and thus a memmove is not needed. */ - n -= 32; - memcpy (dfx->holdback, buf+n, 32); - dfx->holdbacklen = 32; - } - else if (!dfx->holdbacklen) - { - /* EOF seen but empty holdback buffer. This means that we did - * not read enough for the two auth tags. */ - n -= 32; - memcpy (buf, buf+32, n ); - dfx->eof_seen = 2; /* EOF with incomplete tag. */ - } - else - { - /* EOF seen (i.e. read less than 32 bytes). */ - memcpy (buf, dfx->holdback, 32); - n -= 32; - memcpy (dfx->holdback, buf+n, 32); - dfx->eof_seen = 1; /* Normal EOF. */ - } + /* Prepare a new chunk. */ + dfx->chunklen = 0; + dfx->chunkindex++; + err = aead_set_nonce (dfx); + if (err) + goto leave; + err = aead_set_ad (dfx, 0); + if (err) + goto leave; - if (DBG_FILTER) - log_debug ("decrypt: chunklen=%ju total=%ju size=%zu n=%zu%s\n", - (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, size, n, - dfx->eof_seen? " eof":""); + continue; + } - /* Now decrypt the buffer. */ - if (n && dfx->eof_seen > 1) + if (dfx->eof_seen) { - err = gpg_error (GPG_ERR_TRUNCATED); + /* This is the last block of the last chunk. Its length may + * not be a multiple of the block length. */ + gcry_cipher_final (dfx->cipher_hd); } - else if (!n) + err = gcry_cipher_decrypt (dfx->cipher_hd, buf + off, len, NULL, 0); + if (err) { - log_assert (dfx->eof_seen); - err = gpg_error (GPG_ERR_EOF); + log_error ("gcry_cipher_decrypt failed (2): %s\n", gpg_strerror (err)); + goto leave; } - else + totallen += len; + dfx->chunklen += len; + dfx->total += len; + if (dfx->eof_seen) { - size_t off = 0; - - if (dfx->chunklen + n >= dfx->chunksize) - { - size_t n0 = dfx->chunksize - dfx->chunklen; - - if (DBG_FILTER) - log_debug ("chunksize will be reached: n0=%zu\n", n0); - gcry_cipher_final (dfx->cipher_hd); - err = gcry_cipher_decrypt (dfx->cipher_hd, buf, n0, NULL, 0); - if (err) - { - log_error ("gcry_cipher_decrypt failed (1): %s\n", - gpg_strerror (err)); - goto leave; - } - /*log_printhex (buf, n, "buf:");*/ - dfx->chunklen += n0; - dfx->total += n0; - off = n0; - n -= n0; + if (DBG_FILTER) + log_debug ("eof seen: holdback buffer has the tags.\n"); - if (DBG_FILTER) - log_debug ("bytes left: %zu off=%zu\n", n, off); - log_assert (n >= 16); - log_assert (dfx->holdbacklen); - if (DBG_CRYPTO) - log_printhex (buf+off, 16, "tag:"); - err = gcry_cipher_checktag (dfx->cipher_hd, buf + off, 16); - if (err) - { - if (DBG_FILTER) - log_debug ("gcry_cipher_checktag failed (1): %s\n", - gpg_strerror (err)); - /* Return Bad Signature like we do with MDC encryption. */ - if (gpg_err_code (err) == GPG_ERR_CHECKSUM) - err = gpg_error (GPG_ERR_BAD_SIGNATURE); - goto leave; - } - /* Remove that tag from the output. */ - memmove (buf + off, buf + off + 16, n - 16); - n -= 16; - - /* Prepare a new chunk. */ - dfx->chunklen = 0; - dfx->chunkindex++; - err = aead_set_nonce (dfx); - if (err) - goto leave; - err = aead_set_ad (dfx, 0); - if (err) - goto leave; - } + log_assert (dfx->holdbacklen >= 32); - if (dfx->eof_seen) + if (DBG_FILTER) + log_printhex (dfx->holdback, 16, "tag:"); + err = gcry_cipher_checktag (dfx->cipher_hd, dfx->holdback, 16); + if (err) { - /* This is the last block of the last chunk. Its length may - * not be a multiple of the block length. We expect that it - * is followed by two authtags. The first being the one - * from the current chunk and the second form the final - * chunk encrypting the empty string. Note that for the - * other blocks we assume a multiple of the block length - * which is only true because the filter is called with - * large 2^n sized buffers. There is no assert because - * gcry_cipher_decrypt would detect such an error. */ - gcry_cipher_final (dfx->cipher_hd); - /* log_printhex (buf+off, n, "buf+off:"); */ + log_error ("gcry_cipher_checktag failed (2): %s\n", + gpg_strerror (err)); + goto leave; } - err = gcry_cipher_decrypt (dfx->cipher_hd, buf + off, n, NULL, 0); + + /* Check the final chunk. */ + dfx->chunkindex++; + err = aead_set_nonce (dfx); + if (err) + goto leave; + err = aead_set_ad (dfx, 1); + if (err) + goto leave; + gcry_cipher_final (dfx->cipher_hd); + /* decrypt an empty string. */ + err = gcry_cipher_decrypt (dfx->cipher_hd, dfx->holdback, 0, NULL, 0); if (err) { - log_error ("gcry_cipher_decrypt failed (2): %s\n", + log_error ("gcry_cipher_decrypt failed (final): %s\n", gpg_strerror (err)); goto leave; } - dfx->chunklen += n; - dfx->total += n; - - if (dfx->eof_seen) + /* log_printhex (dfx->holdback+16, 16, "tag:"); */ + err = gcry_cipher_checktag (dfx->cipher_hd, dfx->holdback+16, 16); + if (err) { - log_printhex (buf+off, n, "buf+off:"); - if (DBG_FILTER) - log_debug ("eof seen: chunklen=%ju total=%ju off=%zu n=%zu\n", - (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, off, n); - - log_assert (dfx->holdbacklen); - err = gcry_cipher_checktag (dfx->cipher_hd, dfx->holdback, 16); - if (err) - { - log_printhex (dfx->holdback, 16, "tag:"); - log_error ("gcry_cipher_checktag failed (2): %s\n", - gpg_strerror (err)); - /* Return Bad Signature like we do with MDC encryption. */ - if (gpg_err_code (err) == GPG_ERR_CHECKSUM) - err = gpg_error (GPG_ERR_BAD_SIGNATURE); - goto leave; - } - - /* Check the final chunk. */ - dfx->chunkindex++; - err = aead_set_nonce (dfx); - if (err) - goto leave; - err = aead_set_ad (dfx, 1); - if (err) - goto leave; - gcry_cipher_final (dfx->cipher_hd); - /* decrypt an empty string. */ - err = gcry_cipher_decrypt (dfx->cipher_hd, buf, 0, NULL, 0); - if (err) - { - log_error ("gcry_cipher_decrypt failed (final): %s\n", - gpg_strerror (err)); - goto leave; - } - err = gcry_cipher_checktag (dfx->cipher_hd, dfx->holdback+16, 16); - if (err) - { - if (DBG_FILTER) - log_debug ("gcry_cipher_checktag failed (final): %s\n", - gpg_strerror (err)); - /* Return Bad Signature like we do with MDC encryption. */ - if (gpg_err_code (err) == GPG_ERR_CHECKSUM) - err = gpg_error (GPG_ERR_BAD_SIGNATURE); - goto leave; - } - - n += off; if (DBG_FILTER) - log_debug ("eof seen: returning %zu\n", n); - /* log_printhex (buf, n, "buf:"); */ + log_debug ("gcry_cipher_checktag failed (final): %s\n", + gpg_strerror (err)); + goto leave; } - else - n += off; + err = gpg_error (GPG_ERR_EOF); } leave: - /* In case of a real error we better wipe out the buffer than to - * keep partly encrypted data. */ + if (DBG_FILTER) + log_debug ("aead_underflow: returning %zu (%s)\n", + totallen, gpg_strerror (err)); + + /* In case of an auth error we map the error code to the same as + * used by the MDC decryption. */ + if (gpg_err_code (err) == GPG_ERR_CHECKSUM) + err = gpg_error (GPG_ERR_BAD_SIGNATURE); + + /* In case of an error we better wipe out the buffer than to convey + * partly decrypted data. */ if (err && gpg_err_code (err) != GPG_ERR_EOF) memset (buf, 0, size); - *ret_len = n; + + *ret_len = totallen; return err; } commit 83a15fa88e91d277811b6d030c4aa40c4fb3e6ad Author: Werner Koch Date: Wed Jan 24 08:59:06 2018 +0100 gpg: Rename a variable in decrypt-data for clarity. * g10/decrypt-data.c (decode_filter_context_s): Rename field 'defer' to 'holdback' and replace 'defer_filled' flag into 'holdbacklen'. Change all users. Signed-off-by: Werner Koch diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 3d7d747..fc72472 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -56,11 +56,10 @@ struct decode_filter_context_s /* The start IV for AEAD encryption. */ byte startiv[16]; - /* The holdback buffer. For AEAD we need 32 bytes for MDC 22 bytes - * are enough. The flag indicates whether the holdback buffer is - * filled. */ - char defer[32]; - unsigned int defer_filled : 1; + /* The holdback buffer and its used length. For AEAD we need at + * least 32+1 byte for MDC 22 bytes are required. */ + char holdback[48]; + unsigned int holdbacklen; /* Working on a partial length packet. */ unsigned int partial : 1; @@ -512,16 +511,16 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) log_assert (dfx->cipher_hd); log_assert (dfx->mdc_hash); - gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0); - gcry_md_write (dfx->mdc_hash, dfx->defer, 2); + gcry_cipher_decrypt (dfx->cipher_hd, dfx->holdback, 22, NULL, 0); + gcry_md_write (dfx->mdc_hash, dfx->holdback, 2); gcry_md_final (dfx->mdc_hash); - if ( dfx->defer[0] != '\xd3' - || dfx->defer[1] != '\x14' + if ( dfx->holdback[0] != '\xd3' + || dfx->holdback[1] != '\x14' || datalen != 20 - || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->defer+2, datalen)) + || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->holdback+2, datalen)) rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - /* log_printhex("MDC message:", dfx->defer, 22); */ + /* log_printhex("MDC message:", dfx->holdback, 22); */ /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */ } @@ -568,18 +567,18 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) { /* We got 32 bytes from A which are good for the last chunk's * auth tag and the final chunk's auth tag. On the first time - * we don't have anything in the defer buffer and thus we move + * we don't have anything in the holdback buffer and thus we move * those 32 bytes to the start of the buffer. All further calls - * will copy the deferred 32 bytes to the start of the + * will copy the 32 bytes from the holdback buffer to the start of the * buffer. */ - if (!dfx->defer_filled) + if (!dfx->holdbacklen) { memcpy (buf, buf+32, 32); n = 32; /* Continue at this position. */ } else { - memcpy (buf, dfx->defer, 32); + memcpy (buf, dfx->holdback, 32); } /* Now fill up the provided buffer. */ @@ -611,16 +610,16 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) dfx->eof_seen = 1; /* Normal EOF. */ } - /* Move the trailing 32 bytes back to the defer buffer. We + /* Move the trailing 32 bytes back to the holdback buffer. We * got at least 64 bytes and thus a memmove is not needed. */ n -= 32; - memcpy (dfx->defer, buf+n, 32); - dfx->defer_filled = 1; + memcpy (dfx->holdback, buf+n, 32); + dfx->holdbacklen = 32; } - else if (!dfx->defer_filled) + else if (!dfx->holdbacklen) { - /* EOF seen but empty defer buffer. This means that we did not - * read enough for the two auth tags. */ + /* EOF seen but empty holdback buffer. This means that we did + * not read enough for the two auth tags. */ n -= 32; memcpy (buf, buf+32, n ); dfx->eof_seen = 2; /* EOF with incomplete tag. */ @@ -628,9 +627,9 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) else { /* EOF seen (i.e. read less than 32 bytes). */ - memcpy (buf, dfx->defer, 32); + memcpy (buf, dfx->holdback, 32); n -= 32; - memcpy (dfx->defer, buf+n, 32); + memcpy (dfx->holdback, buf+n, 32); dfx->eof_seen = 1; /* Normal EOF. */ } @@ -676,7 +675,7 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) if (DBG_FILTER) log_debug ("bytes left: %zu off=%zu\n", n, off); log_assert (n >= 16); - log_assert (dfx->defer_filled); + log_assert (dfx->holdbacklen); if (DBG_CRYPTO) log_printhex (buf+off, 16, "tag:"); err = gcry_cipher_checktag (dfx->cipher_hd, buf + off, 16); @@ -717,7 +716,7 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) * large 2^n sized buffers. There is no assert because * gcry_cipher_decrypt would detect such an error. */ gcry_cipher_final (dfx->cipher_hd); - /*log_printhex (buf+off, n, "buf+off:");*/ + /* log_printhex (buf+off, n, "buf+off:"); */ } err = gcry_cipher_decrypt (dfx->cipher_hd, buf + off, n, NULL, 0); if (err) @@ -731,15 +730,16 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) if (dfx->eof_seen) { - /* log_printhex (buf+off, n, "buf+off:"); */ + log_printhex (buf+off, n, "buf+off:"); if (DBG_FILTER) log_debug ("eof seen: chunklen=%ju total=%ju off=%zu n=%zu\n", (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, off, n); - log_assert (dfx->defer_filled); - err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer, 16); + log_assert (dfx->holdbacklen); + err = gcry_cipher_checktag (dfx->cipher_hd, dfx->holdback, 16); if (err) { + log_printhex (dfx->holdback, 16, "tag:"); log_error ("gcry_cipher_checktag failed (2): %s\n", gpg_strerror (err)); /* Return Bad Signature like we do with MDC encryption. */ @@ -765,7 +765,7 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) gpg_strerror (err)); goto leave; } - err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer+16, 16); + err = gcry_cipher_checktag (dfx->cipher_hd, dfx->holdback+16, 16); if (err) { if (DBG_FILTER) @@ -881,8 +881,8 @@ mdc_decode_filter (void *opaque, int control, IOBUF a, } if (n == 44) { - /* We have enough stuff - flush the deferred stuff. */ - if ( !dfx->defer_filled ) /* First time. */ + /* We have enough stuff - flush the holdback buffer. */ + if ( !dfx->holdbacklen ) /* First time. */ { memcpy (buf, buf+22, 22); n = 22; @@ -890,7 +890,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a, else { - memcpy (buf, dfx->defer, 22); + memcpy (buf, dfx->holdback, 22); } /* Fill up the buffer. */ if (dfx->partial) @@ -921,13 +921,13 @@ mdc_decode_filter (void *opaque, int control, IOBUF a, dfx->eof_seen = 1; /* Normal EOF. */ } - /* Move the trailing 22 bytes back to the defer buffer. We + /* Move the trailing 22 bytes back to the holdback buffer. We have at least 44 bytes thus a memmove is not needed. */ n -= 22; - memcpy (dfx->defer, buf+n, 22 ); - dfx->defer_filled = 1; + memcpy (dfx->holdback, buf+n, 22 ); + dfx->holdbacklen = 22; } - else if ( !dfx->defer_filled ) /* EOF seen but empty defer buffer. */ + else if ( !dfx->holdbacklen ) /* EOF seen but empty holdback. */ { /* This is bad because it means an incomplete hash. */ n -= 22; @@ -936,9 +936,9 @@ mdc_decode_filter (void *opaque, int control, IOBUF a, } else /* EOF seen (i.e. read less than 22 bytes). */ { - memcpy (buf, dfx->defer, 22 ); + memcpy (buf, dfx->holdback, 22 ); n -= 22; - memcpy (dfx->defer, buf+n, 22 ); + memcpy (dfx->holdback, buf+n, 22 ); dfx->eof_seen = 1; /* Normal EOF. */ } commit f3ef8b0dcaede1c85da0dff8eeceda6a994f0b28 Author: Werner Koch Date: Tue Jan 23 19:08:16 2018 +0100 gpg: New option --chunk-size. * g10/gpg.c (opts): New option --chunk-size. (oChunkSize): New const. (build_list_aead_test_algo, build_list_aead_algo_name): New. (my_strusage): List AEAD algos. (main): Implement --chunk-size.. * g10/options.h (struct opt): Add field 'chunk_size'. (DBG_IPC): Remove duplicated macro. * g10/main.h (DEFAULT_AEAD_ALGO): Depend on Libgcrypt version. * g10/misc.c (openpgp_aead_test_algo): Ditto. * g10/cipher-aead.c: Silence if not in debug mode. * g10/decrypt-data.c: Ditto. -- And that new option immediatley revealed bugs in our chunking code :-(. diff --git a/doc/gpg.texi b/doc/gpg.texi index 35bb9a8..1e6ea59 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2255,6 +2255,16 @@ works properly with such messages, there is often a desire to set a maximum file size that will be generated before processing is forced to stop by the OS limits. Defaults to 0, which means "no limit". + at item --chunk-size @var{n} + at opindex chunk-size +The AEAD encryption mode encrypts the data in chunks so that a +receiving side can check for transmission errors or tampering at the +end of each chunk and does not need to delay this until all data has +been received. The used chunk size is 2^@var{n} byte. The lowest +allowed value for @var{n} is 6 (64 byte) and the largest is 62 (4 +EiB). The default value for @var{n} is 30 which creates chunks not +larger than 1 GiB. + @item --input-size-hint @var{n} @opindex input-size-hint This option can be used to tell GPG the size of the input data in @@ -2592,6 +2602,16 @@ is the default. @itemx --no-force-v4-certs These options are obsolete and have no effect since GnuPG 2.1. + at item --force-aead + at opindex force-aead +Force the use of AEAD encryption over MDC encryption. AEAD is a +modern and faster way to do authenticated encrytion than the old MDC +method. See also options @option{--aead-algo} and + at option{--chunk-size}. + +This option requires the use of option @option{--rfc4880bis} to +declare that a not yet standardized feature is used. + @item --force-mdc @opindex force-mdc Force the use of encryption with a modification detection code. This @@ -2623,6 +2643,16 @@ preferences, as GPG will only select an algorithm that is usable by all recipients. The most highly ranked cipher in this list is also used for the @option{--symmetric} encryption command. + at item --personal-aead-preferences @var{string} + at opindex personal-aead-preferences +Set the list of personal AEAD preferences to @var{string}. Use + at command{@gpgname --version} to get a list of available algorithms, +and use @code{none} to set no preference at all. This allows the user +to safely override the algorithm chosen by the recipient key +preferences, as GPG will only select an algorithm that is usable by +all recipients. The most highly ranked cipher in this list is also +used for the @option{--symmetric} encryption command. + @item --personal-digest-preferences @var{string} @opindex personal-digest-preferences Set the list of personal digest preferences to @var{string}. Use @@ -2981,17 +3011,28 @@ Use @var{name} as cipher algorithm. Running the program with the command @option{--version} yields a list of supported algorithms. If this is not used the cipher algorithm is selected from the preferences stored with the key. In general, you do not want to use this option as -it allows you to violate the OpenPGP standard. +it allows you to violate the OpenPGP standard. The option @option{--personal-cipher-preferences} is the safe way to accomplish the same thing. + at item --aead-algo @var{name} + at opindex aead-algo +Specify that the AEAD algorithm @var{name} is to be used. This is +useful for symmetric encryption where no key preference are available +to select the AEAD algorithm. Runing @command{@gpgname} with option + at option{--version} shows the available AEAD algorithms. In general, +you do not want to use this option as it allows you to violate the +OpenPGP standard. The option @option{--personal-aead-preferences} is +the safe way to accomplish the same thing. + @item --digest-algo @var{name} @opindex digest-algo Use @var{name} as the message digest algorithm. Running the program -with the command @option{--version} yields a list of supported algorithms. In -general, you do not want to use this option as it allows you to -violate the OpenPGP standard. @option{--personal-digest-preferences} is the -safe way to accomplish the same thing. +with the command @option{--version} yields a list of supported +algorithms. In general, you do not want to use this option as it +allows you to violate the OpenPGP standard. The option + at option{--personal-digest-preferences} is the safe way to accomplish +the same thing. @item --compress-algo @var{name} @opindex compress-algo @@ -3013,8 +3054,9 @@ significant in low memory situations. Note, however, that PGP (all versions) only supports ZIP compression. Using any algorithm other than ZIP or "none" will make the message unreadable with PGP. In general, you do not want to use this option as it allows you to -violate the OpenPGP standard. @option{--personal-compress-preferences} is the -safe way to accomplish the same thing. +violate the OpenPGP standard. The option + at option{--personal-compress-preferences} is the safe way to accomplish +the same thing. @item --cert-digest-algo @var{name} @opindex cert-digest-algo diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index 637bd71..9cb57bd 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -86,7 +86,8 @@ set_additional_data (cipher_filter_context_t *cfx, int final) ad[19] = cfx->total >> 8; ad[20] = cfx->total; } - log_printhex (ad, final? 21 : 13, "authdata:"); + if (DBG_CRYPTO) + log_printhex (ad, final? 21 : 13, "authdata:"); return gcry_cipher_authenticate (cfx->cipher_hd, ad, final? 21 : 13); } @@ -124,7 +125,8 @@ set_nonce (cipher_filter_context_t *cfx) nonce[i++] ^= cfx->chunkindex >> 8; nonce[i++] ^= cfx->chunkindex; - log_printhex (nonce, 15, "nonce:"); + if (DBG_CRYPTO) + log_printhex (nonce, 15, "nonce:"); return gcry_cipher_setiv (cfx->cipher_hd, nonce, i); } @@ -149,7 +151,8 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) if (err) goto leave; - cfx->chunkbyte = 10; + log_assert (opt.chunk_size >= 6 && opt.chunk_size <= 62); + cfx->chunkbyte = opt.chunk_size - 6; cfx->chunksize = (uint64_t)1 << (cfx->chunkbyte + 6); cfx->chunklen = 0; cfx->bufsize = AEAD_ENC_BUFFER_SIZE; @@ -170,8 +173,9 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) pkt.pkttype = PKT_ENCRYPTED_AEAD; pkt.pkt.encrypted = &ed; - log_debug ("aead packet: len=%lu extralen=%d\n", - (unsigned long)ed.len, ed.extralen); + if (DBG_FILTER) + log_debug ("aead packet: len=%lu extralen=%d\n", + (unsigned long)ed.len, ed.extralen); write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", cfx->dek->algo, ed.aead_algo); @@ -193,7 +197,8 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) if (err) goto leave; - log_printhex (cfx->dek->key, cfx->dek->keylen, "thekey:"); + if (DBG_CRYPTO) + log_printhex (cfx->dek->key, cfx->dek->keylen, "thekey:"); err = gcry_cipher_setkey (cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen); if (err) return err; @@ -226,7 +231,6 @@ write_auth_tag (cipher_filter_context_t *cfx, iobuf_t a) err = my_iobuf_write (a, tag, 16); if (err) goto leave; - log_printhex (tag, 16, "wrote tag:"); leave: return err; @@ -272,7 +276,8 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) size_t n; /* Put the data into a buffer, flush and encrypt as needed. */ - log_debug ("flushing %zu bytes (cur buflen=%zu)\n", size, cfx->buflen); + if (DBG_FILTER) + log_debug ("flushing %zu bytes (cur buflen=%zu)\n", size, cfx->buflen); do { if (cfx->buflen + size < cfx->bufsize) @@ -284,10 +289,11 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) { size_t n1 = cfx->chunksize - cfx->chunklen; newchunk = 1; - log_debug ("chunksize %ju reached;" - " cur buflen=%zu using %zu of %zu\n", - (uintmax_t)cfx->chunksize, (uintmax_t)cfx->buflen, - n1, n); + if (DBG_FILTER) + log_debug ("chunksize %ju reached;" + " cur buflen=%zu using %zu of %zu\n", + (uintmax_t)cfx->chunksize, (uintmax_t)cfx->buflen, + n1, n); n = n1; } @@ -298,11 +304,14 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) if (cfx->buflen == cfx->bufsize || newchunk) { - log_debug ("encrypting: buflen=%zu %s %p\n", - cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd); + if (DBG_FILTER) + log_debug ("encrypting: buflen=%zu %s %p\n", + cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd); if (newchunk) gcry_cipher_final (cfx->cipher_hd); - if (newchunk) + if (!DBG_FILTER) + ; + else if (newchunk) log_printhex (cfx->buffer, cfx->buflen, "plain(1):"); else if (cfx->buflen > 32) log_printhex (cfx->buffer + cfx->buflen - 32, 32, @@ -314,7 +323,7 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) * mode. */ gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, NULL, 0); - if (newchunk) + if (newchunk && DBG_FILTER) log_printhex (cfx->buffer, cfx->buflen, "ciphr(1):"); err = my_iobuf_write (a, cfx->buffer, cfx->buflen); if (err) @@ -325,18 +334,19 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size) if (newchunk) { - log_debug ("chunklen=%ju total=%ju\n", - (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total); + if (DBG_FILTER) + log_debug ("chunklen=%ju total=%ju\n", + (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total); err = write_auth_tag (cfx, a); if (err) { - log_debug ("gcry_cipher_gettag failed: %s\n", + log_error ("gcry_cipher_gettag failed: %s\n", gpg_strerror (err)); goto leave; } - log_debug ("starting a new chunk (cur size=%zu)\n", size); - log_printhex (buf, size, "cur buf:"); + if (DBG_FILTER) + log_debug ("starting a new chunk (cur size=%zu)\n", size); cfx->chunkindex++; cfx->chunklen = 0; err = set_nonce (cfx); @@ -373,10 +383,10 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) /* Encrypt any remaining bytes. */ if (cfx->buflen) { - log_debug ("processing last %zu bytes of the last chunk\n", cfx->buflen); - log_printhex (cfx->buffer, cfx->buflen, "plain(2):"); + if (DBG_FILTER) + log_debug ("processing last %zu bytes of the last chunk\n", + cfx->buflen); gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, NULL, 0); - log_printhex (cfx->buffer, cfx->buflen, "ciphr(2):"); err = my_iobuf_write (a, cfx->buffer, cfx->buflen); if (err) goto leave; @@ -386,14 +396,16 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a) } /* Get and write the authentication tag. */ - log_debug ("chunklen=%ju total=%ju\n", - (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total); + if (DBG_FILTER) + log_debug ("chunklen=%ju total=%ju\n", + (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total); err = write_auth_tag (cfx, a); if (err) goto leave; /* Write the final chunk. */ - log_debug ("creating final chunk\n"); + if (DBG_FILTER) + log_debug ("creating final chunk\n"); err = write_final_chunk (cfx, a); leave: diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 46650f2..3d7d747 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -150,7 +150,8 @@ aead_set_nonce (decode_filter_ctx_t dfx) nonce[i++] ^= dfx->chunkindex >> 8; nonce[i++] ^= dfx->chunkindex; - log_printhex (nonce, i, "nonce:"); + if (DBG_CRYPTO) + log_printhex (nonce, i, "nonce:"); return gcry_cipher_setiv (dfx->cipher_hd, nonce, i); } @@ -186,7 +187,8 @@ aead_set_ad (decode_filter_ctx_t dfx, int final) ad[19] = dfx->total >> 8; ad[20] = dfx->total; } - log_printhex (ad, final? 21 : 13, "authdata:"); + if (DBG_CRYPTO) + log_printhex (ad, final? 21 : 13, "authdata:"); return gcry_cipher_authenticate (dfx->cipher_hd, ad, final? 21 : 13); } @@ -327,7 +329,8 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) if (rc) goto leave; /* Should never happen. */ - log_printhex (dek->key, dek->keylen, "thekey:"); + if (DBG_CRYPTO) + log_printhex (dek->key, dek->keylen, "thekey:"); rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen); if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY) { @@ -631,9 +634,10 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) dfx->eof_seen = 1; /* Normal EOF. */ } - log_debug ("decrypt: chunklen=%ju total=%ju size=%zu n=%zu%s\n", - (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, size, n, - dfx->eof_seen? " eof":""); + if (DBG_FILTER) + log_debug ("decrypt: chunklen=%ju total=%ju size=%zu n=%zu%s\n", + (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, size, n, + dfx->eof_seen? " eof":""); /* Now decrypt the buffer. */ if (n && dfx->eof_seen > 1) @@ -653,12 +657,13 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) { size_t n0 = dfx->chunksize - dfx->chunklen; - log_debug ("chunksize will be reached: n0=%zu\n", n0); + if (DBG_FILTER) + log_debug ("chunksize will be reached: n0=%zu\n", n0); gcry_cipher_final (dfx->cipher_hd); err = gcry_cipher_decrypt (dfx->cipher_hd, buf, n0, NULL, 0); if (err) { - log_debug ("gcry_cipher_decrypt failed (1): %s\n", + log_error ("gcry_cipher_decrypt failed (1): %s\n", gpg_strerror (err)); goto leave; } @@ -668,15 +673,18 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) off = n0; n -= n0; - log_debug ("bytes left: %zu off=%zu\n", n, off); + if (DBG_FILTER) + log_debug ("bytes left: %zu off=%zu\n", n, off); log_assert (n >= 16); log_assert (dfx->defer_filled); - log_printhex (buf+off, 16, "tag:"); + if (DBG_CRYPTO) + log_printhex (buf+off, 16, "tag:"); err = gcry_cipher_checktag (dfx->cipher_hd, buf + off, 16); if (err) { - log_debug ("gcry_cipher_checktag failed (1): %s\n", - gpg_strerror (err)); + if (DBG_FILTER) + log_debug ("gcry_cipher_checktag failed (1): %s\n", + gpg_strerror (err)); /* Return Bad Signature like we do with MDC encryption. */ if (gpg_err_code (err) == GPG_ERR_CHECKSUM) err = gpg_error (GPG_ERR_BAD_SIGNATURE); @@ -714,7 +722,8 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) err = gcry_cipher_decrypt (dfx->cipher_hd, buf + off, n, NULL, 0); if (err) { - log_debug ("gcry_cipher_decrypt failed (2): %s\n",gpg_strerror (err)); + log_error ("gcry_cipher_decrypt failed (2): %s\n", + gpg_strerror (err)); goto leave; } dfx->chunklen += n; @@ -723,14 +732,15 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) if (dfx->eof_seen) { /* log_printhex (buf+off, n, "buf+off:"); */ - log_debug ("eof seen: chunklen=%ju total=%ju off=%zu n=%zu\n", - (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, off, n); + if (DBG_FILTER) + log_debug ("eof seen: chunklen=%ju total=%ju off=%zu n=%zu\n", + (uintmax_t)dfx->chunklen, (uintmax_t)dfx->total, off, n); log_assert (dfx->defer_filled); err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer, 16); if (err) { - log_debug ("gcry_cipher_checktag failed (2): %s\n", + log_error ("gcry_cipher_checktag failed (2): %s\n", gpg_strerror (err)); /* Return Bad Signature like we do with MDC encryption. */ if (gpg_err_code (err) == GPG_ERR_CHECKSUM) @@ -751,15 +761,16 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) err = gcry_cipher_decrypt (dfx->cipher_hd, buf, 0, NULL, 0); if (err) { - log_debug ("gcry_cipher_decrypt failed (final): %s\n", + log_error ("gcry_cipher_decrypt failed (final): %s\n", gpg_strerror (err)); goto leave; } err = gcry_cipher_checktag (dfx->cipher_hd, dfx->defer+16, 16); if (err) { - log_debug ("gcry_cipher_checktag failed (final): %s\n", - gpg_strerror (err)); + if (DBG_FILTER) + log_debug ("gcry_cipher_checktag failed (final): %s\n", + gpg_strerror (err)); /* Return Bad Signature like we do with MDC encryption. */ if (gpg_err_code (err) == GPG_ERR_CHECKSUM) err = gpg_error (GPG_ERR_BAD_SIGNATURE); @@ -767,7 +778,8 @@ aead_underflow (decode_filter_ctx_t dfx, iobuf_t a, byte *buf, size_t *ret_len) } n += off; - log_debug ("eof seen: returning %zu\n", n); + if (DBG_FILTER) + log_debug ("eof seen: returning %zu\n", n); /* log_printhex (buf, n, "buf:"); */ } else diff --git a/g10/gpg.c b/g10/gpg.c index 2ae3e8a..283de20 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -105,6 +105,7 @@ enum cmd_and_opt_values oBatch = 500, oMaxOutput, oInputSizeHint, + oChunkSize, oSigNotation, oCertNotation, oShowNotation, @@ -596,6 +597,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")), ARGPARSE_p_u (oMaxOutput, "max-output", "@"), ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"), + ARGPARSE_s_i (oChunkSize, "chunk-size", "@"), ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), ARGPARSE_s_n (oQuiet, "quiet", "@"), @@ -1016,6 +1018,18 @@ build_list_cipher_algo_name (int algo) } static int +build_list_aead_test_algo (int algo) +{ + return openpgp_aead_test_algo (algo); +} + +static const char * +build_list_aead_algo_name (int algo) +{ + return openpgp_aead_algo_name (algo); +} + +static int build_list_md_test_algo (int algo) { /* By default we do not accept MD5 based signatures. To avoid @@ -1036,7 +1050,7 @@ build_list_md_algo_name (int algo) static const char * my_strusage( int level ) { - static char *digests, *pubkeys, *ciphers, *zips, *ver_gcry; + static char *digests, *pubkeys, *ciphers, *zips, *aeads, *ver_gcry; const char *p; switch( level ) { @@ -1096,13 +1110,20 @@ my_strusage( int level ) p = ciphers; break; case 36: + if (!aeads) + aeads = build_list ("AEAD: ", 'A', + build_list_aead_algo_name, + build_list_aead_test_algo); + p = aeads; + break; + case 37: if( !digests ) digests = build_list(_("Hash: "), 'H', build_list_md_algo_name, build_list_md_test_algo ); p = digests; break; - case 37: + case 38: if( !zips ) zips = build_list(_("Compression: "),'Z', compress_algo_to_string, @@ -1123,6 +1144,7 @@ build_list (const char *text, char letter, membuf_t mb; int indent; int i, j, len; + int limit; const char *s; char *string; @@ -1133,7 +1155,8 @@ build_list (const char *text, char letter, len = 0; init_membuf (&mb, 512); - for (i=0; i <= 110; i++ ) + limit = (letter == 'A')? 4 : 110; + for (i=0; i <= limit; i++ ) { if (!chkf (i) && (s = mapf (i))) { @@ -2648,6 +2671,10 @@ main (int argc, char **argv) opt.input_size_hint = string_to_u64 (pargs.r.ret_str); break; + case oChunkSize: + opt.chunk_size = pargs.r.ret_int; + break; + case oQuiet: opt.quiet = 1; break; case oNoTTY: tty_no_terminal(1); break; case oDryRun: opt.dry_run = 1; break; @@ -3836,6 +3863,21 @@ main (int argc, char **argv) keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP)) log_error(_("invalid personal compress preferences\n")); + /* Check chunk size. Please fix also the man page if you chnage + * the default. The limits are given by the specs. */ + if (!opt.chunk_size) + opt.chunk_size = 30; /* Default to 1 GiB chunks. */ + else if (opt.chunk_size < 6) + { + opt.chunk_size = 6; + log_info (_("chunk size invalid - using %d\n"), opt.chunk_size); + } + else if (opt.chunk_size > 62) + { + opt.chunk_size = 62; + log_info (_("chunk size invalid - using %d\n"), opt.chunk_size); + } + /* We don't support all possible commands with multifile yet */ if(multifile) { diff --git a/g10/main.h b/g10/main.h index a02c574..2f7c159 100644 --- a/g10/main.h +++ b/g10/main.h @@ -41,7 +41,11 @@ # define DEFAULT_CIPHER_ALGO CIPHER_ALGO_3DES #endif -#define DEFAULT_AEAD_ALGO AEAD_ALGO_EAX +#if GCRYPT_VERSION_NUMBER < 0x019000 +# define DEFAULT_AEAD_ALGO AEAD_ALGO_OCB +#else +# define DEFAULT_AEAD_ALGO AEAD_ALGO_EAX +#endif #define DEFAULT_DIGEST_ALGO ((GNUPG)? DIGEST_ALGO_SHA256:DIGEST_ALGO_SHA1) #define DEFAULT_S2K_DIGEST_ALGO DIGEST_ALGO_SHA1 diff --git a/g10/misc.c b/g10/misc.c index 36d3bdc..8c54793 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -591,11 +591,23 @@ openpgp_cipher_algo_name (cipher_algo_t algo) gpg_error_t openpgp_aead_test_algo (aead_algo_t algo) { + /* FIXME: We currently have no easy way to test whether libgcrypt + * implements a mode. The only way we can do this is to open a + * cipher context with that mode and close it immediately. That is + * a bit costly. So we look at the libgcrypt version and assume + * nothing has been patched out. */ switch (algo) { case AEAD_ALGO_NONE: break; + case AEAD_ALGO_EAX: +#if GCRYPT_VERSION_NUMBER < 0x010900 + break; +#else + return 0; +#endif + case AEAD_ALGO_OCB: return 0; } diff --git a/g10/options.h b/g10/options.h index 36bea69..471aee7 100644 --- a/g10/options.h +++ b/g10/options.h @@ -62,6 +62,9 @@ struct * progress info and to decide on how to allocate buffers. */ uint64_t input_size_hint; + /* The AEAD chunk size expressed as a power of 2. */ + int chunk_size; + int dry_run; int autostart; int list_only; @@ -319,7 +322,6 @@ struct { #define DBG_TRUST (opt.debug & DBG_TRUST_VALUE) #define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) #define DBG_IPC (opt.debug & DBG_IPC_VALUE) -#define DBG_IPC (opt.debug & DBG_IPC_VALUE) #define DBG_CLOCK (opt.debug & DBG_CLOCK_VALUE) #define DBG_LOOKUP (opt.debug & DBG_LOOKUP_VALUE) #define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE) ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 56 ++++++- g10/cipher-aead.c | 81 ++++++---- g10/decrypt-data.c | 461 ++++++++++++++++++++++++++++------------------------- g10/gpg.c | 48 +++++- g10/main.h | 6 +- g10/misc.c | 12 ++ g10/options.h | 4 +- 7 files changed, 407 insertions(+), 261 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 24 18:45:53 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 24 Jan 2018 18:45:53 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.3-128-gdb7661b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via db7661b5a297a58c95fa9873d43f31d697b8feb3 (commit) via bfc11816444512b4ebcc6617d3c3b5988e753de3 (commit) from ff1bdc23d9f1693c1add7c1fe8d218b7bf743e31 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit db7661b5a297a58c95fa9873d43f31d697b8feb3 Author: Werner Koch Date: Wed Jan 24 18:29:08 2018 +0100 gpg: New maintainer option --debug-set-iobuf-size. * g10/gpg.c (opts): Add new option. (opt_set_iobuf_size): New var. (set_debug): Set the option. * tests/openpgp/armor.scm: Use this option to revert the buffer size to the one which used to exhibit the tested bugs. Signed-off-by: Werner Koch diff --git a/common/iobuf.c b/common/iobuf.c index bf59778..02c9b49 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -59,9 +59,7 @@ /*-- Begin configurable part. --*/ -/* The size of the internal buffers. - NOTE: If you change this value you MUST also adjust the regression - test "armored_key_8192" in armor.test! */ +/* The standard size of the internal buffers. */ #define DEFAULT_IOBUF_BUFFER_SIZE (64*1024) /* To avoid a potential DoS with compression packets we better limit diff --git a/doc/gpg.texi b/doc/gpg.texi index 1e6ea59..83b234e 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2859,6 +2859,12 @@ Set all useful debugging flags. Set stdout into line buffered mode. This option is only honored when given on the command line. + at item --debug-set-iobuf-size @var{n} + at opindex debug-iolbf +Change the buffer size of the IOBUFs to @var{n} kilobyte. Using 0 +prints the current size. Note well: This is a maintainer only option +and may thus be changed or removed at any time without notice. + @item --faked-system-time @var{epoch} @opindex faked-system-time This option is only useful for testing; it sets the system time back or diff --git a/g10/gpg.c b/g10/gpg.c index 283de20..cbac967 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -223,6 +223,7 @@ enum cmd_and_opt_values oDebugLevel, oDebugAll, oDebugIOLBF, + oDebugSetIobufSize, oStatusFD, oStatusFile, oAttributeFD, @@ -642,6 +643,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oDebugLevel, "debug-level", "@"), ARGPARSE_s_n (oDebugAll, "debug-all", "@"), ARGPARSE_s_n (oDebugIOLBF, "debug-iolbf", "@"), + ARGPARSE_s_u (oDebugSetIobufSize, "debug-set-iobuf-size", "@"), ARGPARSE_s_i (oStatusFD, "status-fd", "@"), ARGPARSE_s_s (oStatusFile, "status-file", "@"), ARGPARSE_s_i (oAttributeFD, "attribute-fd", "@"), @@ -956,6 +958,8 @@ int g10_errors_seen = 0; static int utf8_strings = 0; static int maybe_setuid = 1; +static unsigned int opt_set_iobuf_size; +static unsigned int opt_set_iobuf_size_used; static char *build_list( const char *text, char letter, const char *(*mapf)(int), int (*chkf)(int) ); @@ -1276,6 +1280,10 @@ set_debug (const char *level) if (opt.debug) parse_debug_flag (NULL, &opt.debug, debug_flags); + + if (opt_set_iobuf_size || opt_set_iobuf_size_used) + log_debug ("iobuf buffer size is %uk\n", + iobuf_set_buffer_size (opt_set_iobuf_size)); } @@ -2742,6 +2750,11 @@ main (int argc, char **argv) case oDebugIOLBF: break; /* Already set in pre-parse step. */ + case oDebugSetIobufSize: + opt_set_iobuf_size = pargs.r.ret_ulong; + opt_set_iobuf_size_used = 1; + break; + case oStatusFD: set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); break; diff --git a/tests/openpgp/armor.scm b/tests/openpgp/armor.scm index 3c117dd..a1b0aa9 100755 --- a/tests/openpgp/armor.scm +++ b/tests/openpgp/armor.scm @@ -191,7 +191,7 @@ nW1ff9rt1YcTH9LiiE4EGBECAAYFAjnKLe0AEgkQ3uyMCd5BWw4HZUdQRwABAZeBAKDsa7tc (info "Checking armored_key_8192") (pipe:do (pipe:echo armored_key_8192) - (pipe:gpg '(--import))) + (pipe:gpg '(--debug-set-iobuf-size=8 --import))) (define nopad_armored_msg "-----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.11-svn5139 (GNU/Linux) @@ -758,10 +758,10 @@ wg7Md81a5RI3F2FG8747t9gX (info "Importing alpha_seckey") (pipe:do (pipe:echo alpha_seckey) - (pipe:gpg '(--import))) + (pipe:gpg '(--debug-set-iobuf-size=8 --import))) (info "Checking for bug #1179") (tr:do (tr:pipe-do (pipe:echo nopad_armored_msg) - (pipe:gpg '(--decrypt)))) + (pipe:gpg '(--debug-set-iobuf-size=8 --decrypt)))) commit bfc11816444512b4ebcc6617d3c3b5988e753de3 Author: Werner Koch Date: Wed Jan 24 18:37:55 2018 +0100 iobuf: Increase the size of the buffer. Add iobuf_set_buffer_size. * common/iobuf.c (IOBUF_BUFFER_SIZE): Rename to DEFAULT_IOBUF_BUFFER_SIZE and increase to 64k. (iobuf_buffer_size): New var. Always use this instead of the macro. (iobuf_set_buffer_size): New. (struct file_filter_ctx_t): Add field delayed_rc. (file_filter) [!W32]: Try to fill the supplied buffer. -- I did some test to see whether this has an effect. A test program piped 100 million random bytes to gpg to symmetric encryption only w/0 compression. Single read means the old behaviour, multi read the new behaviour which fills up the buffer when the read(2) returned only 4k in once call. 8k buffer single read User time (seconds): 0.09 System time (seconds): 0.04 Percent of CPU this job got: 6% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.04 8k buffer multi read User time (seconds): 0.08 System time (seconds): 0.05 Percent of CPU this job got: 6% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.04 64k buffer single read User time (seconds): 0.09 System time (seconds): 0.06 Percent of CPU this job got: 6% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.20 64k buffer multi read User time (seconds): 0.11 System time (seconds): 0.06 Percent of CPU this job got: 8% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.01 128k buffer single read User time (seconds): 0.09 System time (seconds): 0.05 Percent of CPU this job got: 7% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.05 128k buffer multi read User time (seconds): 0.11 System time (seconds): 0.05 Percent of CPU this job got: 8% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.01 512k buffer single read: User time (seconds): 0.08 System time (seconds): 0.08 Percent of CPU this job got: 7% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.21 512k buffer multi read: User time (seconds): 0.10 System time (seconds): 0.06 Percent of CPU this job got: 7% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.05 Does not make much of a difference :-(. Maybe it changes depending on the type of used filters. Signed-off-by: Werner Koch diff --git a/common/iobuf.c b/common/iobuf.c index 5a9fd7c..bf59778 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -62,7 +62,7 @@ /* The size of the internal buffers. NOTE: If you change this value you MUST also adjust the regression test "armored_key_8192" in armor.test! */ -#define IOBUF_BUFFER_SIZE 8192 +#define DEFAULT_IOBUF_BUFFER_SIZE (64*1024) /* To avoid a potential DoS with compression packets we better limit the number of filters in a chain. */ @@ -70,6 +70,10 @@ /*-- End configurable part. --*/ +/* The size of the iobuffers. This can be chnages using the + * iobuf_set_buffer_size fucntion. */ +static unsigned int iobuf_buffer_size = DEFAULT_IOBUF_BUFFER_SIZE; + #ifdef HAVE_W32_SYSTEM # ifdef HAVE_W32CE_SYSTEM @@ -92,6 +96,7 @@ typedef struct int keep_open; int no_cache; int eof_seen; + int delayed_rc; int print_only_name; /* Flags indicating that fname is not a real file. */ char fname[1]; /* Name of the file. */ } file_filter_ctx_t; @@ -167,7 +172,7 @@ static int translate_file_handle (int fd, int for_write); to be sent to A's filter function. If A is a IOBUF_OUTPUT_TEMP filter, then this also enlarges the - buffer by IOBUF_BUFFER_SIZE. + buffer by iobuf_buffer_size. May only be called on an IOBUF_OUTPUT or IOBUF_OUTPUT_TEMP filters. */ static int filter_flush (iobuf_t a); @@ -451,12 +456,20 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, if (control == IOBUFCTRL_UNDERFLOW) { - assert (size); /* We need a buffer. */ + log_assert (size); /* We need a buffer. */ if (a->eof_seen) { rc = -1; *ret_len = 0; } + else if (a->delayed_rc) + { + rc = a->delayed_rc; + a->delayed_rc = 0; + if (rc == -1) + a->eof_seen = -1; + *ret_len = 0; + } else { #ifdef HAVE_W32_SYSTEM @@ -487,29 +500,39 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, int n; nbytes = 0; - do - { - n = read (f, buf, size); - } - while (n == -1 && errno == EINTR); - if (n == -1) - { /* error */ - if (errno != EPIPE) - { - rc = gpg_error_from_syserror (); - log_error ("%s: read error: %s\n", - a->fname, strerror (errno)); - } - } - else if (!n) - { /* eof */ - a->eof_seen = 1; - rc = -1; - } - else - { - nbytes = n; - } + read_more: + do + { + n = read (f, buf + nbytes, size - nbytes); + } + while (n == -1 && errno == EINTR); + if (n > 0) + { + nbytes += n; + if (nbytes < size) + goto read_more; + } + else if (!n) /* eof */ + { + if (nbytes) + a->delayed_rc = -1; + else + { + a->eof_seen = 1; + rc = -1; + } + } + else /* error */ + { + rc = gpg_error_from_syserror (); + if (gpg_err_code (rc) != GPG_ERR_EPIPE) + log_error ("%s: read error: %s\n", a->fname, gpg_strerror (rc)); + if (nbytes) + { + a->delayed_rc = rc; + rc = 0; + } + } #endif *ret_len = nbytes; } @@ -569,6 +592,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, else if (control == IOBUFCTRL_INIT) { a->eof_seen = 0; + a->delayed_rc = 0; a->keep_open = 0; a->no_cache = 0; } @@ -1053,6 +1077,30 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer, return rc; } + +/* Change the default size for all IOBUFs to KILOBYTE. This needs to + * be called before any iobufs are used and can only be used once. + * Returns the current value. Using 0 has no effect except for + * returning the current value. */ +unsigned int +iobuf_set_buffer_size (unsigned int kilobyte) +{ + static int used; + + if (!used && kilobyte) + { + if (kilobyte < 4) + kilobyte = 4; + else if (kilobyte > 16*1024) + kilobyte = 16*1024; + + iobuf_buffer_size = kilobyte * 1024; + used = 1; + } + return iobuf_buffer_size / 1024; +} + + #define MAX_IOBUF_DESC 32 /* * Fill the buffer by the description of iobuf A. @@ -1105,7 +1153,7 @@ iobuf_alloc (int use, size_t bufsize) if (bufsize == 0) { log_bug ("iobuf_alloc() passed a bufsize of 0!\n"); - bufsize = IOBUF_BUFFER_SIZE; + bufsize = iobuf_buffer_size; } a = xcalloc (1, sizeof *a); @@ -1213,7 +1261,7 @@ iobuf_cancel (iobuf_t a) iobuf_t iobuf_temp (void) { - return iobuf_alloc (IOBUF_OUTPUT_TEMP, IOBUF_BUFFER_SIZE); + return iobuf_alloc (IOBUF_OUTPUT_TEMP, iobuf_buffer_size); } iobuf_t @@ -1288,7 +1336,7 @@ do_open (const char *fname, int special_filenames, return NULL; } - a = iobuf_alloc (use, IOBUF_BUFFER_SIZE); + a = iobuf_alloc (use, iobuf_buffer_size); fcx = xmalloc (sizeof *fcx + strlen (fname)); fcx->fp = fp; fcx->print_only_name = print_only; @@ -1335,7 +1383,7 @@ do_iobuf_fdopen (int fd, const char *mode, int keep_open) fp = INT2FD (fd); a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT, - IOBUF_BUFFER_SIZE); + iobuf_buffer_size); fcx = xmalloc (sizeof *fcx + 20); fcx->fp = fp; fcx->print_only_name = 1; @@ -1373,7 +1421,7 @@ iobuf_esopen (estream_t estream, const char *mode, int keep_open) size_t len = 0; a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT, - IOBUF_BUFFER_SIZE); + iobuf_buffer_size); fcx = xtrymalloc (sizeof *fcx + 30); fcx->fp = estream; fcx->print_only_name = 1; @@ -1398,7 +1446,7 @@ iobuf_sockopen (int fd, const char *mode) size_t len; a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT, - IOBUF_BUFFER_SIZE); + iobuf_buffer_size); scx = xmalloc (sizeof *scx + 25); scx->sock = fd; scx->print_only_name = 1; @@ -1599,13 +1647,13 @@ iobuf_push_filter2 (iobuf_t a, increased accordingly. We don't need to allocate a 10 MB buffer for a non-terminal filter. Just use the default size. */ - a->d.size = IOBUF_BUFFER_SIZE; + a->d.size = iobuf_buffer_size; } else if (a->use == IOBUF_INPUT_TEMP) /* Same idea as above. */ { a->use = IOBUF_INPUT; - a->d.size = IOBUF_BUFFER_SIZE; + a->d.size = iobuf_buffer_size; } /* The new filter (A) gets a new buffer. @@ -1922,7 +1970,7 @@ filter_flush (iobuf_t a) if (a->use == IOBUF_OUTPUT_TEMP) { /* increase the temp buffer */ - size_t newsize = a->d.size + IOBUF_BUFFER_SIZE; + size_t newsize = a->d.size + iobuf_buffer_size; if (DBG_IOBUF) log_debug ("increasing temp iobuf from %lu to %lu\n", diff --git a/common/iobuf.h b/common/iobuf.h index 22e02da..1615638 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -259,6 +259,12 @@ struct iobuf_struct EXTERN_UNLESS_MAIN_MODULE int iobuf_debug_mode; +/* Change the default size for all IOBUFs to KILOBYTE. This needs to + * be called before any iobufs are used and can only be used once. + * Returns the current value. Using 0 has no effect except for + * returning the current value. */ +unsigned int iobuf_set_buffer_size (unsigned int kilobyte); + /* Returns whether the specified filename corresponds to a pipe. In particular, this function checks if FNAME is "-" and, if special filenames are enabled (see check_special_filename), whether ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 122 +++++++++++++++++++++++++++++++++--------------- common/iobuf.h | 6 +++ doc/gpg.texi | 6 +++ g10/gpg.c | 13 ++++++ tests/openpgp/armor.scm | 6 +-- 5 files changed, 112 insertions(+), 41 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 25 15:20:06 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 25 Jan 2018 15:20:06 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-12-g91a3d15 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 91a3d15cee32f82a8422e76655a605c5048eaad8 (commit) from 91303b7df9c3e810cfcd4920f78bac6f8b7df2b2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 91a3d15cee32f82a8422e76655a605c5048eaad8 Author: Werner Koch Date: Thu Jan 25 15:14:37 2018 +0100 doc: Note --quick-gen-key as an alias for --quick-generate-key -- diff --git a/doc/gpg.texi b/doc/gpg.texi index 9776a3b..927d77d 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -622,7 +622,9 @@ This section explains the main commands for key management. @table @gnupgtabopt @item --quick-generate-key @var{user-id} [@var{algo} [@var{usage} [@var{expire}]]] + at itemx --quick-gen-key @opindex quick-generate-key + at opindex quick-gen-key This is a simple command to generate a standard key with one user id. In contrast to @option{--generate-key} the key is generated directly without the need to answer a bunch of prompts. Unless the option ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 25 17:05:24 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 25 Jan 2018 17:05:24 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.4-108-g149369a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 149369a92b447d06863e79dfe5589321eaf1f237 (commit) via 91a3d15cee32f82a8422e76655a605c5048eaad8 (commit) via 91303b7df9c3e810cfcd4920f78bac6f8b7df2b2 (commit) via e1e35db510c9222e7a7dc208c2e49df556954170 (commit) via 6fb5713f4a6976900cc70c140e61043b6ef688d1 (commit) via 339b3301ee8410fe3bbdebb66a6e83801d79d40d (commit) via 4d3c500f4793eb263940ff5ef87ec4ead63c9b4b (commit) via 412bb7a801f242d47a82712080cce6ddbb843166 (commit) via 4f88b0f56134af2ce56d434b7acd47fcf9b6f7cf (commit) via a6849888295f0e0872c948cd72a59374bb867777 (commit) via f3ba66781a07af2e32f5887e6e15acdd4822a431 (commit) via 290348e349e8d56a856f187a08e913f2ed525b3c (commit) via 84555d53720cc9240535ed9b57f1efcc9927f6dc (commit) via 558b17593ae97b8a07d06bf0d6af1a626b304501 (commit) via b4975788143b5cbab75534d7274c635986f15e0b (commit) via 43aaf60449036e870cc25b77fbb7312cf3fb534c (commit) via c7b8ec6c8e57797f0b77dbf7fca85fb600323328 (commit) via 7449063b1af2eef73d621a69cdb2fb713ab1ae6c (commit) via faecaf80f0b5f0dd50d4ff20a8ba3bd6a592fe1f (commit) via 3a48455b0baec6e516e16370a63b1175af89e7af (commit) via 482e000b8a7e336f342a7fac3b7379257e944b6e (commit) from db7661b5a297a58c95fa9873d43f31d697b8feb3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 149369a92b447d06863e79dfe5589321eaf1f237 Merge: db7661b 91a3d15 Author: Werner Koch Date: Thu Jan 25 16:48:07 2018 +0100 Merge branch 'STABLE-BRANCH-2-2' into master Signed-off-by: Werner Koch diff --cc NEWS index 216d872,f924176..4fa20b2 --- a/NEWS +++ b/NEWS @@@ -47,7 -51,11 +47,10 @@@ Noteworthy changes in version 2.3.0 (un * agent: Improve robustness of the shutdown pending state. [Git#7ffedfab89] + See-also: gnupg-announce/2017q4/000417.html + + -Noteworthy changes in version 2.2.2 (2017-11-07) ------------------------------------------------- + Changes also found in 2.2.2: * gpg: Avoid duplicate key imports by concurrently running gpg processes. [#3446] @@@ -88,7 -96,11 +91,9 @@@ * Add configure option --enable-werror. [#2423] + See-also: gnupg-announce/2017q4/000416.html + - -Noteworthy changes in version 2.2.1 (2017-09-19) ------------------------------------------------- + Changes also found in 2.2.1: * gpg: Fix formatting of the user id in batch mode key generation if only "name-email" is given. diff --cc common/logging.h index 5a82be4,2225100..a20b8f8 --- a/common/logging.h +++ b/common/logging.h @@@ -145,9 -107,35 +145,36 @@@ void log_flush (void) raw dump, with TEXT being an empty string, print a trailing linefeed, otherwise print an entire debug line with TEXT followed by the hexdump and a final LF. */ -void log_printhex (const char *text, const void *buffer, size_t length); +void log_printhex (const void *buffer, size_t length, const char *text); -void log_clock (const char *string); +void log_clock (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); +#endif /* Use gnupg internal logging functions. */ + + /* Some handy assertion macros which don't abort. */ + + #define return_if_fail(expr) do { \ + if (!(expr)) { \ + log_debug ("%s:%d: assertion '%s' failed\n", \ + __FILE__, __LINE__, #expr ); \ + return; \ + } } while (0) + #define return_null_if_fail(expr) do { \ + if (!(expr)) { \ + log_debug ("%s:%d: assertion '%s' failed\n", \ + __FILE__, __LINE__, #expr ); \ + return NULL; \ + } } while (0) + #define return_val_if_fail(expr,val) do { \ + if (!(expr)) { \ + log_debug ("%s:%d: assertion '%s' failed\n", \ + __FILE__, __LINE__, #expr ); \ + return (val); \ + } } while (0) + #define never_reached() do { \ + log_debug ("%s:%d: oops - should never get here\n", \ + __FILE__, __LINE__ ); \ + } while (0) + + #endif /*GNUPG_COMMON_LOGGING_H*/ ----------------------------------------------------------------------- Summary of changes: NEWS | 5 + common/homedir.c | 2 +- common/logging.h | 27 + configure.ac | 2 +- doc/gpg.texi | 19 +- doc/tools.texi | 8 + doc/wks.texi | 37 +- g10/keygen.c | 67 ++- g10/mainproc.c | 10 +- kbx/kbxutil.c | 1 - kbx/keybox-defs.h | 69 +-- kbx/keybox-util.c | 53 -- kbx/keybox.h | 4 - po/ca.po | 8 +- po/cs.po | 1285 +++++++++++++++++++--------------------------- po/da.po | 7 +- po/de.po | 11 +- po/el.po | 8 +- po/eo.po | 8 +- po/es.po | 7 +- po/et.po | 8 +- po/fi.po | 8 +- po/fr.po | 7 +- po/gl.po | 8 +- po/hu.po | 8 +- po/id.po | 8 +- po/it.po | 8 +- po/ja.po | 10 +- po/nb.po | 7 +- po/nl.po | 4 +- po/pl.po | 7 +- po/pt.po | 8 +- po/ro.po | 13 +- po/ru.po | 14 +- po/sk.po | 9 +- po/sv.po | 7 +- po/tr.po | 7 +- po/uk.po | 7 +- po/zh_CN.po | 8 +- po/zh_TW.po | 7 +- scd/app-openpgp.c | 119 ++++- scd/ccid-driver.c | 17 +- sm/gpgsm.c | 2 - tools/applygnupgdefaults | 2 +- tools/gpg-wks-server.c | 195 ++++++- tools/gpgconf-comp.c | 29 +- tools/gpgconf.c | 112 +++- tools/gpgconf.h | 4 + 48 files changed, 1206 insertions(+), 1075 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 26 02:13:46 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 26 Jan 2018 02:13:46 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-13-g08e686a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 08e686a6a6d5bcb5410228b388745d09686b260c (commit) from 91a3d15cee32f82a8422e76655a605c5048eaad8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 08e686a6a6d5bcb5410228b388745d09686b260c Author: NIIBE Yutaka Date: Fri Jan 26 10:08:29 2018 +0900 agent: More fix for get_client_pid for portability. * configure.ac: Check sys/ucred.h instead of ucred.h. * agent/command-ssh.c: Include sys/ucred.h. -- It's *BSD and macOS thing. Fixes-commit: f7f806afa5083617f4aba02fc3b285b06a7d73d4 Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 9d45a18..213f3f9 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -44,8 +44,8 @@ #include #include #endif /*!HAVE_W32_SYSTEM*/ -#ifdef HAVE_UCRED_H -#include +#ifdef HAVE_SYS_UCRED_H +#include #endif #include "agent.h" diff --git a/configure.ac b/configure.ac index c3fce31..424ce7b 100644 --- a/configure.ac +++ b/configure.ac @@ -1278,7 +1278,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \ pty.h utmp.h pwd.h inttypes.h signal.h sys/select.h \ stdint.h signal.h util.h libutil.h termios.h \ - ucred.h sys/sysmacros.h sys/mkdev.h]) + sys/ucred.h sys/sysmacros.h sys/mkdev.h]) AC_HEADER_TIME ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 4 ++-- configure.ac | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 26 02:46:35 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 26 Jan 2018 02:46:35 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-14-gd7207b3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via d7207b39b71d1b07c4cddac602f29ec583f6d1ad (commit) from 08e686a6a6d5bcb5410228b388745d09686b260c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d7207b39b71d1b07c4cddac602f29ec583f6d1ad Author: NIIBE Yutaka Date: Fri Jan 26 10:42:31 2018 +0900 agent: Fix last commit. * configure.ac: Check ucred.h as well as sys/ucred.h. * agent/command-ssh.c: Add inclusion of ucred.h. -- It was T2981, adding ucred.h for Solaris. We also need sys/ucred.h for FreeBSD and macOS. Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 213f3f9..e0b7238 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -47,6 +47,9 @@ #ifdef HAVE_SYS_UCRED_H #include #endif +#ifdef HAVE_UCRED_H +#include +#endif #include "agent.h" diff --git a/configure.ac b/configure.ac index 424ce7b..420af92 100644 --- a/configure.ac +++ b/configure.ac @@ -1278,7 +1278,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \ pty.h utmp.h pwd.h inttypes.h signal.h sys/select.h \ stdint.h signal.h util.h libutil.h termios.h \ - sys/ucred.h sys/sysmacros.h sys/mkdev.h]) + ucred.h sys/ucred.h sys/sysmacros.h sys/mkdev.h]) AC_HEADER_TIME ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 3 +++ configure.ac | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 26 02:59:24 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 26 Jan 2018 02:59:24 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.4-112-g660eafa Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 660eafa3a9f68e116e9b0597edc317d8ff90f9b2 (commit) via c2e69a7a8c4b21e125babd50e464e71e1535f173 (commit) via d7207b39b71d1b07c4cddac602f29ec583f6d1ad (commit) via 08e686a6a6d5bcb5410228b388745d09686b260c (commit) from 149369a92b447d06863e79dfe5589321eaf1f237 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 660eafa3a9f68e116e9b0597edc317d8ff90f9b2 Author: NIIBE Yutaka Date: Fri Jan 26 10:52:56 2018 +0900 agent: Fix sending connecting process uid to pinentry. * agent/command-ssh.c (get_client_info): Use LOCAL_PEERCRED. -- LOCAL_PEERUID was wrong (while there is LOCAL_PEERUUID). For FreeBSD and macOS, we can use LOCAL_PEERCRED to get uid. GnuPG-bug-id: 3757 Fixes-commit: 28aa6890588cc108639951bb4bef03ac17743046 Signed-off-by: NIIBE Yutaka diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 4ec02ec..7155446 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -3622,7 +3622,15 @@ get_client_info (int fd, struct peer_info_s *out) socklen_t len = sizeof (pid_t); getsockopt (fd, SOL_LOCAL, LOCAL_PEERPID, &client_pid, &len); - getsockopt (fd, SOL_LOCAL, LOCAL_PEERUID, &client_uid, &len); +#if defined (LOCAL_PEERCRED) + { + struct xucred cr; + len = sizeof (struct xucred); + + if (!getsockopt (fd, SOL_LOCAL, LOCAL_PEERCRED, &cr, &len)) + client_uid = cr.cr_uid; + } +#endif } #elif defined (LOCAL_PEEREID) { commit c2e69a7a8c4b21e125babd50e464e71e1535f173 Merge: 149369a d7207b3 Author: NIIBE Yutaka Date: Fri Jan 26 10:47:28 2018 +0900 Merge branch 'STABLE-BRANCH-2-2' into master Signed-off-by: NIIBE Yutaka ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 13 ++++++++++++- configure.ac | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 26 12:59:24 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 26 Jan 2018 12:59:24 +0100 Subject: [git] gnupg-doc - branch, master, updated. 25761b4696f65c72692edd0100fc188cabc441c6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 25761b4696f65c72692edd0100fc188cabc441c6 (commit) from f8a54305c4e3354fba02f9b2da5b9683d92a6c4c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 25761b4696f65c72692edd0100fc188cabc441c6 Author: Werner Koch Date: Fri Jan 26 12:53:56 2018 +0100 verein: Add links to the annual accounts 2017 diff --git a/web/verein/finances.org b/web/verein/finances.org index b5af434..df5fd80 100644 --- a/web/verein/finances.org +++ b/web/verein/finances.org @@ -8,9 +8,10 @@ This page gives an overview on the financial state of the GnuPG e.V. Note that in general the name of a donor is not public; for larger donations we will however publish the name. If you have any - questions on certain transactions, please write to board at . + questions on certain transactions, please write to board at . For the + annual accounts see [[*Annual%20Accounts][below]]. -** Euro transaction +** Transaction in 2017 Here are the transactions on our bank account in 2017 @@ -20,14 +21,14 @@ Here are the transactions on our bank account in 2017 | 2017-06-30 | | 2.23 | 197.77 | Bank fees | | 2017-07-10 | 2000.00 | | 2197.77 | Donation: German company | | 2017-07-25 | 59005.30 | | 61203.07 | Transfer from WHS | -| 2017-07-31 | | 5.80 | 61198.27 | Bank fees | +| 2017-07-31 | | 5.80 | 61197.27 | Bank fees | | 2017-08-31 | | 5.00 | 61192.27 | Bank fees | | 2017-09-07 | 3615.64 | | 64807.91 | Exchange of 1 BTC | | 2017-09-11 | 38650.36 | | 103458.27 | Exchange of 10 BTC | | 2017-09-14 | 35868.08 | | 139326.35 | Exchange of 10 BTC | | 2017-09-19 | | 119.00 | 139207.35 | Design postcards | | 2017-09-29 | | 12.00 | 139195.35 | Banking card | -| 2017-09-29 | | 6.30 | 139190.05 | Bank fees | +| 2017-09-29 | | 6.30 | 139189.05 | Bank fees | | 2017-10-06 | 18197.53 | | 157386.58 | Exchange of 5 BTC | | 2017-10-12 | 220.00 | | 157606.58 | Donation kernel-recipes | | 2017-10-12 | 310.00 | | 157916.58 | Donation kernel-recipes | @@ -41,11 +42,20 @@ The 59.000 ? from the Wau Holland Stiftung have been collected by them for the GnuPG project since 2013. After the Verein reached charitable state they were able to transfer that money. Many thanks to them. -We have produced two postcards to be used as giveaways at shows and -other opportunities. Our account has not yet been charged for -printing costs. - -** Bitcoin transactions - As of 2018-01-02 we own 0.4608 confirmed BTC. 26 BTC have been transferred to our Euro account in September/October 2017 (see above). + +We produced two kinds of postcards to be used as giveaways at shows +and other opportunities. + +** Transaction in 2018 + +| Date | Debit | Credit | Balance | Description | +|------------+---------+--------+-----------+--------------------------| +| 2018-01-16 | 1000.00 | | 158900.38 | Donation: German company | + + + +* Annual Accounts + +- Annual accounts for 2017: [[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf][pdf]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.html][html]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.html.sig][sig]]) ----------------------------------------------------------------------- Summary of changes: web/verein/finances.org | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 26 15:21:35 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 26 Jan 2018 15:21:35 +0100 Subject: [git] gnupg-doc - branch, master, updated. e88b83be6c386d0579a0c8bdb141f5104bb88b69 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via e88b83be6c386d0579a0c8bdb141f5104bb88b69 (commit) from 25761b4696f65c72692edd0100fc188cabc441c6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e88b83be6c386d0579a0c8bdb141f5104bb88b69 Author: Werner Koch Date: Fri Jan 26 15:16:09 2018 +0100 verein: Link to the German translation of the annual accounst 2017 diff --git a/web/verein/finances.org b/web/verein/finances.org index df5fd80..2686a40 100644 --- a/web/verein/finances.org +++ b/web/verein/finances.org @@ -58,4 +58,4 @@ and other opportunities. * Annual Accounts -- Annual accounts for 2017: [[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf][pdf]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.html][html]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.html.sig][sig]]) +- Annual accounts for 2017: [[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf][pdf]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.html][html]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.html.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.de.pdf][pdf (German)]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf.sig][sig]]) ----------------------------------------------------------------------- Summary of changes: web/verein/finances.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 26 15:40:52 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 26 Jan 2018 15:40:52 +0100 Subject: [git] gnupg-doc - branch, master, updated. 5227081f8bc0d221e261a0553f4353b697068cd7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 5227081f8bc0d221e261a0553f4353b697068cd7 (commit) from e88b83be6c386d0579a0c8bdb141f5104bb88b69 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5227081f8bc0d221e261a0553f4353b697068cd7 Author: Werner Koch Date: Fri Jan 26 15:35:26 2018 +0100 verein: URL fix diff --git a/web/verein/finances.org b/web/verein/finances.org index 2686a40..a25de6e 100644 --- a/web/verein/finances.org +++ b/web/verein/finances.org @@ -11,7 +11,7 @@ questions on certain transactions, please write to board at . For the annual accounts see [[*Annual%20Accounts][below]]. -** Transaction in 2017 +** Transactions in 2017 Here are the transactions on our bank account in 2017 @@ -48,7 +48,7 @@ transferred to our Euro account in September/October 2017 (see above). We produced two kinds of postcards to be used as giveaways at shows and other opportunities. -** Transaction in 2018 +** Transactions in 2018 | Date | Debit | Credit | Balance | Description | |------------+---------+--------+-----------+--------------------------| @@ -58,4 +58,4 @@ and other opportunities. * Annual Accounts -- Annual accounts for 2017: [[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf][pdf]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.html][html]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.html.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.de.pdf][pdf (German)]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf.sig][sig]]) +- Annual accounts for 2017: [[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf][pdf]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.pdf.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.html][html]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.html.sig][sig]]) [[https://gnupg.org/ftp/verein/annual-accounts-2017.de.pdf][pdf (German)]] ([[https://gnupg.org/ftp/verein/annual-accounts-2017.de.pdf.sig][sig]]) ----------------------------------------------------------------------- Summary of changes: web/verein/finances.org | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jan 27 19:51:50 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 27 Jan 2018 19:51:50 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-15-gf8e868d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via f8e868d9dfb6fc1390e421e7993a1d076309ed83 (commit) from d7207b39b71d1b07c4cddac602f29ec583f6d1ad (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f8e868d9dfb6fc1390e421e7993a1d076309ed83 Author: Werner Koch Date: Sat Jan 27 19:46:19 2018 +0100 dirmngr: Improve assuan error comment for cmd keyserver. * dirmngr/server.c: Add error comment in case --resolve fails in ensure_keyserver. -- GnuPG-bug-id: 3756 Signed-off-by: Werner Koch diff --git a/dirmngr/server.c b/dirmngr/server.c index 3d0768b..ab2ca85 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -2134,8 +2134,13 @@ cmd_keyserver (assuan_context_t ctx, char *line) if (resolve_flag) { err = ensure_keyserver (ctrl); - if (!err) - err = ks_action_resolve (ctrl, ctrl->server_local->keyservers); + if (err) + { + assuan_set_error (ctx, err, + "Bad keyserver configuration in dirmngr.conf"); + goto leave; + } + err = ks_action_resolve (ctrl, ctrl->server_local->keyservers); if (err) goto leave; } ----------------------------------------------------------------------- Summary of changes: dirmngr/server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 29 01:35:53 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 29 Jan 2018 01:35:53 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.4-16-g64aa98c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 64aa98c8a05513d9c00f53a2b880d80f9035333e (commit) from f8e868d9dfb6fc1390e421e7993a1d076309ed83 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 64aa98c8a05513d9c00f53a2b880d80f9035333e Author: NIIBE Yutaka Date: Mon Jan 29 09:34:37 2018 +0900 tests: Fix for NetBSD with __func__. * tests/asschk.c: Don't define __func__ if available. -- NetBSD 7.0 has __func__ defined. Signed-off-by: NIIBE Yutaka diff --git a/tests/asschk.c b/tests/asschk.c index 2595c0a..65828e5 100644 --- a/tests/asschk.c +++ b/tests/asschk.c @@ -116,7 +116,7 @@ #endif #if __STDC_VERSION__ < 199901L -# if __GNUC__ >= 2 +# if __GNUC__ >= 2 && !defined (__func__) # define __func__ __FUNCTION__ # else /* Let's try our luck here. Some systems may provide __func__ without ----------------------------------------------------------------------- Summary of changes: tests/asschk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 29 03:48:17 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 29 Jan 2018 03:48:17 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-2-g37d62e9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 37d62e9d0f685c257fdb5f303e60ff01f8a36a2f (commit) from 7da01c7352d41eb33e445968b248544d301588f9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 37d62e9d0f685c257fdb5f303e60ff01f8a36a2f Author: NIIBE Yutaka Date: Mon Jan 29 11:45:33 2018 +0900 core: Implement _gpgme_getenv for NetBSD. * src/get-env.c [HAVE_GETENV_R] (_gpgme_getenv): New. -- GnuPG-bug-id: 3056 Signed-off-by: NIIBE Yutaka diff --git a/src/get-env.c b/src/get-env.c index 57fd419..9e2df68 100644 --- a/src/get-env.c +++ b/src/get-env.c @@ -28,7 +28,7 @@ #include "util.h" -#if defined(HAVE_THREAD_SAFE_GETENV) || !defined (HAVE_GETENV_R) +#if defined(HAVE_THREAD_SAFE_GETENV) /* We prefer using getenv() if it is thread-safe. */ /* Retrieve the environment variable NAME and return a copy of it in a @@ -50,7 +50,46 @@ _gpgme_getenv (const char *name, char **value) } return 0; } +#elif defined (HAVE_GETENV_R) +#define INITIAL_GETENV_SIZE 32 +gpgme_error_t +_gpgme_getenv (const char *name, char **value) +{ + size_t len = INITIAL_GETENV_SIZE; + char *env_value; + + env_value = malloc (len); + + while (1) + { + *value = env_value; + if (!env_value) + return gpg_error_from_syserror (); + + if (getenv_r (name, env_value, len) == 0) + break; + + if (errno == ERANGE) + { + len *= 2; + env_value = realloc (env_value, len); + } + else + { + int saved = errno; + + free (env_value); + *value = NULL; + if (errno == ENOENT) + return 0; + else + return gpg_error_from_errno (saved); + } + } + + return 0; +} #else /* FIXME: Implement this when we have the specification for it. */ ----------------------------------------------------------------------- Summary of changes: src/get-env.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 29 04:06:19 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 29 Jan 2018 04:06:19 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-3-g58130b9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 58130b97f6582455fd355ac58ae3182a28812cfc (commit) from 37d62e9d0f685c257fdb5f303e60ff01f8a36a2f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 58130b97f6582455fd355ac58ae3182a28812cfc Author: NIIBE Yutaka Date: Mon Jan 29 12:04:55 2018 +0900 tests: Fix for NetBSD. * tests/gpg/pinentry: Use /bin/sh instead of Bash. Signed-off-by: NIIBE Yutaka diff --git a/tests/gpg/pinentry b/tests/gpg/pinentry index 3b99726..b12caae 100755 --- a/tests/gpg/pinentry +++ b/tests/gpg/pinentry @@ -1,4 +1,4 @@ -#! /bin/bash +#! /bin/sh # Dummy pinentry # # Copyright 2008 g10 Code GmbH ----------------------------------------------------------------------- Summary of changes: tests/gpg/pinentry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 29 10:57:10 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 29 Jan 2018 10:57:10 +0100 Subject: [git] NTBTLS - branch, master, updated. ntbtls-0.1.2-2-g0b56e5c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Not Too Bad TLS". The branch, master has been updated via 0b56e5c076ae22853bf919c696db1e994acd1ef0 (commit) from 5dcdd1b0a399493f2f6c8e9cc2a51736057905a0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0b56e5c076ae22853bf919c696db1e994acd1ef0 Author: NIIBE Yutaka Date: Mon Jan 29 18:54:51 2018 +0900 Fix wipemem.h for other architectures. * src/wipemem.h (FASTWIPE_T): Defined. -- GnuPG-bug-id: 3207 Signed-off-by: NIIBE Yutaka diff --git a/src/wipemem.h b/src/wipemem.h index 0ddaf10..ac5bebf 100644 --- a/src/wipemem.h +++ b/src/wipemem.h @@ -33,6 +33,7 @@ defined(__aarch64__) # define _fast_wipememory2_unaligned_head(_ptr,_set,_len) /*do nothing*/ # else +#define FASTWIPE_T uint64_t # define _fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do \ { \ while((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1) && _vlen) \ ----------------------------------------------------------------------- Summary of changes: src/wipemem.h | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- Not Too Bad TLS http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 29 11:40:37 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 29 Jan 2018 11:40:37 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-4-gbbb5e70 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via bbb5e70e7e8598978b6c61b13ba77705ff86e469 (commit) from 58130b97f6582455fd355ac58ae3182a28812cfc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bbb5e70e7e8598978b6c61b13ba77705ff86e469 Author: NIIBE Yutaka Date: Mon Jan 29 19:38:49 2018 +0900 Fix compile error message. * src/get-env.c (_gpgme_getenv): Fix error message. Signed-off-by: NIIBE Yutaka diff --git a/src/get-env.c b/src/get-env.c index 9e2df68..1adbeee 100644 --- a/src/get-env.c +++ b/src/get-env.c @@ -92,7 +92,6 @@ _gpgme_getenv (const char *name, char **value) } #else -/* FIXME: Implement this when we have the specification for it. */ -#error Use of getenv_r not implemented. +#error No thread-safe getenv nor getenv_r #endif ----------------------------------------------------------------------- Summary of changes: src/get-env.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 30 00:25:08 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 30 Jan 2018 00:25:08 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.10.0-5-g59fcabb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 59fcabbdf537b2745ef0c3cae908b21970a5b39b (commit) from bbb5e70e7e8598978b6c61b13ba77705ff86e469 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 59fcabbdf537b2745ef0c3cae908b21970a5b39b Author: NIIBE Yutaka Date: Tue Jan 30 08:22:57 2018 +0900 Fix for BSD Make. * tests/gpg/Makefile.am, tests/gpgsm/Makefile.am: Remove ./. -- GNU Make is powerful enough for handling and interpreting of pathname as target, but BSD Make is not. GnuPG-bug-id: 3056 Signed-off-by: NIIBE Yutaka diff --git a/tests/gpg/Makefile.am b/tests/gpg/Makefile.am index 642e0a0..a2d2411 100644 --- a/tests/gpg/Makefile.am +++ b/tests/gpg/Makefile.am @@ -96,7 +96,7 @@ private-keys-v1.d/gpg-sample.stamp: $(srcdir)/$(private_keys) done echo x > ./private-keys-v1.d/gpg-sample.stamp -pubring-stamp: $(srcdir)/pubdemo.asc ./private-keys-v1.d/gpg-sample.stamp +pubring-stamp: $(srcdir)/pubdemo.asc private-keys-v1.d/gpg-sample.stamp $(GPG) --batch --no-permission-warning \ --import $(srcdir)/pubdemo.asc -$(GPG) --batch --no-permission-warning \ diff --git a/tests/gpgsm/Makefile.am b/tests/gpgsm/Makefile.am index 4ab2283..9d47e2a 100644 --- a/tests/gpgsm/Makefile.am +++ b/tests/gpgsm/Makefile.am @@ -59,7 +59,7 @@ export GPG_AGENT_INFO := BUILT_SOURCES = gpgsm.conf trustlist.txt pubring-stamp \ private-keys-v1.d/gpg-sample.stamp -pubring-stamp: $(srcdir)/cert_g10code_test1.der ./private-keys-v1.d/gpg-sample.stamp +pubring-stamp: $(srcdir)/cert_g10code_test1.der private-keys-v1.d/gpg-sample.stamp $(GPGSM) --import $(srcdir)/cert_g10code_test1.der touch pubring-stamp ----------------------------------------------------------------------- Summary of changes: tests/gpg/Makefile.am | 2 +- tests/gpgsm/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 30 11:06:15 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 30 Jan 2018 11:06:15 +0100 Subject: [git] GpgOL - branch, async-enc, created. gpgol-2.0.6-2-gbec715a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been created at bec715ab3f57709db1fbf4759b0b0593055b5b04 (commit) - Log ----------------------------------------------------------------- commit bec715ab3f57709db1fbf4759b0b0593055b5b04 Author: Andre Heinecke Date: Tue Jan 30 10:59:28 2018 +0100 First steps for async encryption handling * src/Makefile.am (gpgol_SOURCES): Add new files. * src/common_indep.h (log_mime_data): Shorthand for DBG_MIME_DATA. * src/cryptcontroller.cpp, src/cryptcontroller.h: New. Similar to parsecontroller but the other way around. * src/mail.cpp (do_crypt): New. Thread helper. (Mail::encrypt_sign): Renamed to Mail::encrypt_sign_start. And changed to use cryptcontroller. (Mail::update_crypt_mapi): New. Dummy. (Mail::update_crypt_oom): New. Dummy. (Mail::CryptState): Helper state for encryption. * src/mailitem-events.cpp: Add proof of concept for new enc. * src/mimemaker.h (add_body_and_attachments): Export. * src/windowmessage.h, src/windowmessages.cpp (CRYPTO_DONE): New. -- This shows the general possibility of async crypto by first collecting the data, then doing the crypto and then still to have the possibility to update the encrypted data both in MAPI and in OOM. diff --git a/src/Makefile.am b/src/Makefile.am index 961b2a5..90091cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -84,7 +84,8 @@ gpgol_SOURCES = \ addin-options.cpp addin-options.h \ parsecontroller.cpp parsecontroller.h \ mimedataprovider.cpp mimedataprovider.h \ - explorer-events.cpp explorers-events.cpp + explorer-events.cpp explorers-events.cpp \ + cryptcontroller.cpp cryptcontroller.h #treeview_SOURCES = treeview.c diff --git a/src/common_indep.h b/src/common_indep.h index 124112a..10b14d6 100644 --- a/src/common_indep.h +++ b/src/common_indep.h @@ -297,6 +297,7 @@ void log_hexdump (const void *buf, size_t buflen, const char *fmt, #define log_oom if (opt.enable_debug & DBG_OOM) log_debug #define log_oom_extra if (opt.enable_debug & DBG_OOM_EXTRA) log_debug #define log_mime_parser if (opt.enable_debug & DBG_MIME_PARSER) log_debug +#define log_mime_data if (opt.enable_debug & DBG_MIME_DATA) log_debug #define gpgol_release(X) \ { \ diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp new file mode 100644 index 0000000..f12957f --- /dev/null +++ b/src/cryptcontroller.cpp @@ -0,0 +1,159 @@ +/* @file cryptcontroller.cpp + * @brief Helper to do crypto on a mail. + * + * Copyright (C) 2018 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ +#include "config.h" + +#include "common.h" +#include "cryptcontroller.h" +#include "mail.h" +#include "mapihelp.h" +#include "mimemaker.h" + +#ifdef HAVE_W32_SYSTEM +#include "common.h" +/* We use UTF-8 internally. */ +#undef _ +# define _(a) utf8_gettext (a) +#else +# define _(a) a +#endif +static int +sink_data_write (sink_t sink, const void *data, size_t datalen) +{ + GpgME::Data *d = static_cast(sink->cb_data); + d->write (data, datalen); + return 0; +} + + +/** We have some C Style cruft in here as this was historically how + GpgOL worked directly in the MAPI data objects. To reduce the regression + risk the new object oriented way for crypto reused as much as possible + from this. +*/ +CryptController::CryptController (Mail *mail, bool encrypt, bool sign, + bool doInline, GpgME::Protocol proto): + m_mail (mail), + m_encrypt (encrypt), + m_sign (sign), + m_inline (doInline), + m_proto (proto) +{ + log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.", + SRCNAME, __func__, mail, encrypt, sign, doInline); +} + +CryptController::~CryptController() +{ + log_debug ("%s:%s:%p", + SRCNAME, __func__, m_mail); +} + +int +CryptController::collect_data () +{ + /* Get the attachment info and the body. We need to do this before + creating the engine's filter because sending the cancel to + the engine with nothing for the engine to process. Will result + in an error. This is actually a bug in our engine code but + we better avoid triggering this bug because the engine + sometimes hangs. Fixme: Needs a proper fix. */ + + + /* Take the Body from the mail if possible. This is a fix for + GnuPG-Bug-ID: T3614 because the body is not always properly + updated in MAPI when sending. */ + char *body = m_mail->take_cached_plain_body (); + if (body && !*body) + { + xfree (body); + body = NULL; + } + + LPMESSAGE message = get_oom_base_message (m_mail->item ()); + if (!message) + { + log_error ("%s:%s: Failed to get base message.", + SRCNAME, __func__); + } + + auto att_table = mapi_create_attach_table (message, 0); + int n_att_usable = count_usable_attachments (att_table); + if (!n_att_usable && !body) + { + log_debug ("%s:%s: encrypt empty message", SRCNAME, __func__); + } + + if (n_att_usable && m_inline) + { + log_debug ("%s:%s: PGP Inline not supported for attachments." + " Using PGP MIME", + SRCNAME, __func__); + m_inline = false; + } + else if (m_inline) + { + // Inline. Use Body as input and be done. + m_input.write (body, strlen (body)); + log_debug ("%s:%s: PGP Inline. Using cached body as input.", + SRCNAME, __func__); + gpgol_release (message); + return 0; + } + + /* Set up the sink object to collect the mime structure */ + struct sink_s sinkmem; + sink_t sink = &sinkmem; + memset (sink, 0, sizeof *sink); + sink->cb_data = &m_input; + sink->writefnc = sink_data_write; + + /* Collect the mime strucutre */ + if (add_body_and_attachments (sink, message, att_table, m_mail, + body, n_att_usable)) + { + log_error ("%s:%s: Collecting body and attachments failed.", + SRCNAME, __func__); + gpgol_release (message); + return -1; + } + + /* Message is no longer needed */ + gpgol_release (message); + + /* Set the input buffer to start. */ + m_input.seek (0, SEEK_SET); + return 0; +} + +int +CryptController::do_crypto () +{ + log_debug ("%s:%s:", + SRCNAME, __func__); + return 0; +} + +int +CryptController::update_mail_mapi () +{ + log_debug ("%s:%s:", SRCNAME, __func__); + return 0; +} diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h new file mode 100644 index 0000000..f28c567 --- /dev/null +++ b/src/cryptcontroller.h @@ -0,0 +1,65 @@ +/* @file cryptcontroller.h + * @brief Helper to handle sign and encrypt + * + * Copyright (C) 2018 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ +#ifndef CRYPTCONTROLLER_H +#define CRYPTCONTROLLER_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +class Mail; + +class CryptController +{ +public: + /** @brief Construct a Crypthelper for a Mail object. */ + CryptController (Mail *mail, bool encrypt, bool sign, + bool inlineCrypt, GpgME::Protocol proto); + ~CryptController (); + + /** @brief Collect the data from the mail into the internal + data structures. + + @returns 0 on success. + */ + int collect_data (); + + /** @brief Does the actual crypto work according to op. + Can be called in a different thread then the UI Thread. + + @returns 0 on success. + */ + int do_crypto (); + + /** @brief Update the MAPI structure of the mail with + the result. */ + int update_mail_mapi (); + +private: + Mail *m_mail; + GpgME::Data m_input, m_output; + bool m_encrypt, m_sign, m_inline; + GpgME::Protocol m_proto; +}; + +#endif diff --git a/src/mail.cpp b/src/mail.cpp index 39342b1..a48d1e2 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -33,6 +33,7 @@ #include "gpgoladdin.h" #include "mymapitags.h" #include "parsecontroller.h" +#include "cryptcontroller.h" #include "gpgolstr.h" #include "windowmessages.h" #include "mlang-charset.h" @@ -135,7 +136,8 @@ Mail::Mail (LPDISPATCH mailitem) : m_cached_recipients(nullptr), m_type(MSGTYPE_UNKNOWN), m_do_inline(false), - m_is_gsuite(false) + m_is_gsuite(false), + m_crypt_state(NoCryptMail) { if (get_mail_for_item (mailitem)) { @@ -726,6 +728,68 @@ do_parsing (LPVOID arg) return 0; } +static DWORD WINAPI +do_crypt (LPVOID arg) +{ + gpgrt_lock_lock (&dtor_lock); + /* We lock with mail dtors so we can be sure the mail->parser + call is valid. */ + Mail *mail = (Mail *)arg; + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: canceling crypt for: %p already deleted", + SRCNAME, __func__, arg); + gpgrt_lock_unlock (&dtor_lock); + return 0; + } + if (mail->crypt_state() != Mail::NeedsActualCrypt) + { + log_debug ("%s:%s: invalid state %i", + SRCNAME, __func__, mail->crypt_state ()); + gpgrt_lock_unlock (&dtor_lock); + return -1; + } + + /* This takes a shared ptr of parser. So the parser is + still valid when the mail is deleted. */ + auto crypter = mail->crypter(); + gpgrt_lock_unlock (&dtor_lock); + + if (!crypter) + { + log_error ("%s:%s: no crypter found for mail: %p", + SRCNAME, __func__, arg); + gpgrt_lock_unlock (&parser_lock); + return -1; + } + + /* This can take a while */ + int rc = crypter->do_crypto(); + + gpgrt_lock_lock (&dtor_lock); + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: aborting crypt for: %p already deleted", + SRCNAME, __func__, arg); + gpgrt_lock_unlock (&dtor_lock); + return 0; + } + + if (rc) + { + log_debug ("%s:%s: crypto failed for: %p with: %i", + SRCNAME, __func__, arg, rc); + gpgrt_lock_unlock (&dtor_lock); + return rc; + } + + mail->set_crypt_state (Mail::NeedsUpdateInMAPI); + + do_in_ui_thread (CRYPTO_DONE, arg); + gpgrt_lock_unlock (&dtor_lock); + return 0; +} + bool Mail::is_crypto_mail() const { @@ -981,11 +1045,15 @@ Mail::parsing_done() } int -Mail::encrypt_sign () +Mail::encrypt_sign_start () { - int err = -1, - flags = 0; - protocol_t proto = opt.enable_smime ? PROTOCOL_UNKNOWN : PROTOCOL_OPENPGP; + if (m_crypt_state != NeedsActualCrypt) + { + log_debug ("%s:%s: invalid state %i", + SRCNAME, __func__, m_crypt_state); + return -1; + } + int flags = 0; if (!needs_crypto()) { return 0; @@ -995,9 +1063,10 @@ Mail::encrypt_sign () { log_error ("%s:%s: Failed to get base message.", SRCNAME, __func__); - return err; + return -1; } flags = get_gpgol_draft_info_flags (message); + gpgol_release (message); const auto window = get_active_hwnd (); @@ -1068,35 +1137,29 @@ Mail::encrypt_sign () m_do_inline = m_is_gsuite ? true : opt.inline_pgp; - EnableWindow (window, FALSE); - if (flags == 3) - { - log_debug ("%s:%s: Sign / Encrypting message", - SRCNAME, __func__); - err = message_sign_encrypt (message, proto, - NULL, get_sender ().c_str (), this); - } - else if (flags == 2) + if (m_crypter) { - err = message_sign (message, proto, - NULL, get_sender ().c_str (), this); - } - else if (flags == 1) - { - err = message_encrypt (message, proto, - NULL, get_sender ().c_str (), this); + log_error ("%s:%s: Crypter already exists for mail %p", + SRCNAME, __func__, this); + return -1; } - else + + GpgME::Protocol proto = opt.enable_smime ? GpgME::UnknownProtocol: GpgME::OpenPGP; + m_crypter = std::shared_ptr (new CryptController (this, flags & 1, + flags & 2, + m_do_inline, proto)); + + if (m_crypter->collect_data ()) { - log_debug ("%s:%s: Unknown flags for crypto: %i", - SRCNAME, __func__, flags); + log_error ("%s:%s: Crypter for mail %p failed to collect data.", + SRCNAME, __func__, this); + return -1; } - log_debug ("%s:%s: Status: %i", - SRCNAME, __func__, err); - EnableWindow (window, TRUE); - gpgol_release (message); - m_crypt_successful = !err; - return err; + //EnableWindow (window, FALSE); + CloseHandle(CreateThread (NULL, 0, do_crypt, + (LPVOID) this, 0, + NULL)); + return 0; } int @@ -2431,3 +2494,19 @@ Mail::inline_body_to_body() m_inline_body = std::string(); return ret; } + +void +Mail::update_crypt_mapi() +{ + log_debug ("%s:%s: Update crypt oom", + SRCNAME, __func__); + m_crypt_state = WantsSend; +} + +void +Mail::update_crypt_oom() +{ + log_debug ("%s:%s: Update crypt oom", + SRCNAME, __func__); + m_crypt_state = NeedsSecondAfterWrite; +} diff --git a/src/mail.h b/src/mail.h index 42052e2..389c6e2 100644 --- a/src/mail.h +++ b/src/mail.h @@ -32,6 +32,7 @@ #include class ParseController; +class CryptController; /** @brief Data wrapper around a mailitem. * @@ -47,6 +48,16 @@ class ParseController; class Mail { public: + enum CryptState + { + NoCryptMail, + NeedsFirstAfterWrite, + NeedsActualCrypt, + NeedsUpdateInOOM, + NeedsSecondAfterWrite, + WantsSend + }; + /** @brief Construct a mail object for the item. * * This also installs the event sink for this item. @@ -134,13 +145,13 @@ public: * @returns 0 on success. */ int decrypt_verify (); - /** @brief do crypto operations as selected by the user. + /** @brief start crypto operations as selected by the user. * * Initiates the crypto operations according to the gpgol * draft info flags. * * @returns 0 on success. */ - int encrypt_sign (); + int encrypt_sign_start (); /** @brief Necessary crypto operations were completed successfully. */ bool crypto_successful () { return !needs_crypto() || m_crypt_successful; } @@ -226,6 +237,10 @@ public: only valid while the actual parsing happens. */ std::shared_ptr parser () { return m_parser; } + /** @brief get the associated cryptcontroller. + only valid while the crypting happens. */ + std::shared_ptr crypter () { return m_crypter; } + /** To be called from outside once the paser was done. In Qt this would be a slot that is called once it is finished we hack around that a bit by calling it from our windowmessages @@ -347,6 +362,19 @@ public: /** Set the inline body as OOM body property. */ int inline_body_to_body (); + + /** Get the crypt state */ + CryptState crypt_state () const {return m_crypt_state;} + + /** Set the crypt state */ + void set_crypt_state (CryptState state) {m_crypt_state = state;} + + /** Update MAPI data after encryption. */ + void update_crypt_mapi (); + + /** Update OOM data after encryption. */ + void update_crypt_oom (); + private: void update_categories (); void update_body (); @@ -373,6 +401,7 @@ private: char **m_cached_recipients; msgtype_t m_type; /* Our messagetype as set in mapi */ std::shared_ptr m_parser; + std::shared_ptr m_crypter; GpgME::VerificationResult m_verify_result; GpgME::DecryptionResult m_decrypt_result; GpgME::Signature m_sig; @@ -382,5 +411,6 @@ private: bool m_do_inline; bool m_is_gsuite; /* Are we on a gsuite account */ std::string m_inline_body; + CryptState m_crypt_state; }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index b3161f0..4f1d65f 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -348,11 +348,31 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__); break; } - m_mail->update_oom_data (); - m_mail->set_needs_encrypt (true); - invoke_oom_method (m_object, "Save", NULL); - if (m_mail->crypto_successful ()) + if (m_mail->crypt_state () == Mail::NoCryptMail && + m_mail->needs_crypto ()) + { + // First contact with a mail to encrypt update + // state and oom data. + m_mail->update_oom_data (); + m_mail->set_crypt_state (Mail::NeedsFirstAfterWrite); + + // Save the Mail + invoke_oom_method (m_object, "Save", NULL); + + // The afterwrite in the save should have triggered + // the encryption. We cancel send for our asyncness. + + // Cancel send + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + } + + if (m_mail->crypt_state () == Mail::NeedsUpdateInOOM) + { + m_mail->update_crypt_oom (); + } + + if (m_mail->crypt_state () == Mail::WantsSend) { /* Fishy behavior catcher: Sometimes the save does not clean out the body. Weird. Happened at least for one user. @@ -515,9 +535,17 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_oom_extra ("%s:%s: AfterWrite : %p", SRCNAME, __func__, m_mail); - if (m_mail->needs_encrypt ()) + if (m_mail->crypt_state () == Mail::NeedsFirstAfterWrite) + { + /* Seen the first after write. Advance the state */ + m_mail->set_crypt_state (Mail::NeedsActualCrypt); + m_mail->encrypt_sign_start (); + return S_OK; + } + if (m_mail->crypt_state () == Mail::NeedsSecondAfterWrite) { - m_mail->encrypt_sign (); + m_mail->set_crypt_state (Mail::NeedsUpdateInMAPI); + m_mail->update_crypt_mapi (); return S_OK; } break; diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 53e6049..1f9de4e 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -1403,7 +1403,7 @@ add_body (Mail *mail, const char *boundary, sink_t sink, } /* Add the body and attachments. Does multipart handling. */ -static int +int add_body_and_attachments (sink_t sink, LPMESSAGE message, mapi_attach_item_t *att_table, Mail *mail, const char *body, int n_att_usable) diff --git a/src/mimemaker.h b/src/mimemaker.h index c89a495..2896a60 100644 --- a/src/mimemaker.h +++ b/src/mimemaker.h @@ -73,6 +73,9 @@ int restore_msg_from_moss (LPMESSAGE message, LPDISPATCH moss_att, int count_usable_attachments (mapi_attach_item_t *table); +int add_body_and_attachments (sink_t sink, LPMESSAGE message, + mapi_attach_item_t *att_table, Mail *mail, + const char *body, int n_att_usable); #ifdef __cplusplus } #endif diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index f44b9df..815c217 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -88,6 +88,32 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) Mail::close (mail); break; } + case (CRYPTO_DONE): + { + auto mail = (Mail*) ctx->data; + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: Crypto done for mail which is gone.", + SRCNAME, __func__); + break; + } + // modify the mail. + if (mail->crypt_state (Mail::NeedsUpdateInOOM)) + { + mail->update_crypt_oom(); + } + if (mail->crypt_state (Mail::NeedsSecondAfterWrite)) + { + // Save the Mail + log_debug ("%s:%s: Crypto done for %p Invoking second save.", + SRCNAME, __func__, mail); + invoke_oom_method (mail->item (), "Save", NULL); + log_debug ("%s:%s: Second save done for %p Invoking second send.", + SRCNAME, __func__, mail); + } + // Finaly this should pass. + invoke_oom_method (mail->item (), "Send", NULL); + } default: log_debug ("Unknown msg"); } diff --git a/src/windowmessages.h b/src/windowmessages.h index f53ecd4..a278675 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -42,7 +42,8 @@ typedef enum _gpgol_wmsg_type to the mail object. */ RECIPIENT_ADDED = 3, /* A recipient was added. Data should be ptr to mail */ - CLOSE = 4, /* Send the message in the next event loop. */ + CLOSE = 4, /* Close the message in the next event loop. */ + CRYPTO_DONE = 5, /* Sign / Encrypt done. */ } gpgol_wmsg_type; typedef struct ----------------------------------------------------------------------- hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 30 14:22:08 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 30 Jan 2018 14:22:08 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-4-ge789048 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via e789048f47fccab444df477f6e82ece69fa2a8b4 (commit) via e133064eb799de9a1138f23afc5cd13d1b053fdf (commit) from bec715ab3f57709db1fbf4759b0b0593055b5b04 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e789048f47fccab444df477f6e82ece69fa2a8b4 Author: Andre Heinecke Date: Tue Jan 30 14:19:42 2018 +0100 Make inline encryption work in the new way * src/cryptcontroller.cpp (CryptController::resolve_keys): Dummy. Should resolve keys in the future. (CryptController::do_crypto): Do something. (CryptController::get_inline_data): Take data as string. * src/cryptcontroller.h Update accordingly. * src/mail.cpp (Mail::append_to_inline_body): Use cryptcontroller. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index f12957f..ebb18bb 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -26,6 +26,10 @@ #include "mapihelp.h" #include "mimemaker.h" +#include +#include +#include + #ifdef HAVE_W32_SYSTEM #include "common.h" /* We use UTF-8 internally. */ @@ -54,6 +58,7 @@ CryptController::CryptController (Mail *mail, bool encrypt, bool sign, m_encrypt (encrypt), m_sign (sign), m_inline (doInline), + m_crypto_success (false), m_proto (proto) { log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.", @@ -115,6 +120,8 @@ CryptController::collect_data () log_debug ("%s:%s: PGP Inline. Using cached body as input.", SRCNAME, __func__); gpgol_release (message); + /* Set the input buffer to start. */ + m_input.seek (0, SEEK_SET); return 0; } @@ -144,10 +151,127 @@ CryptController::collect_data () } int +CryptController::resolve_keys () +{ + m_recipients.clear(); + + /*XXX Temporary hack part do key resolution here. */ + GpgME::Error err; + auto ctx = std::shared_ptr (GpgME::Context::createForProtocol(GpgME::OpenPGP)); + const auto key = ctx->key ("EB4C5A5B7AD6C8527F050BAF1ED4F0BC6CFBC912", err, true); + + if (key.isNull()) + { + log_error ("%s:%s: Failure to resolve keys.", + SRCNAME, __func__); + return -1; + } + + m_recipients.push_back(key); + m_signer_key = key; + return 0; +} + +int CryptController::do_crypto () { + // TODO get recipients and sender and protocol. + log_debug ("%s:%s:", SRCNAME, __func__); + auto ctx = std::shared_ptr (GpgME::Context::createForProtocol(GpgME::OpenPGP)); + + if (!ctx) + { + log_error ("%s:%s: Failure to create context.", + SRCNAME, __func__); + return -1; + } + + if (resolve_keys ()) + { + log_debug ("%s:%s: Failure to resolve keys.", + SRCNAME, __func__); + return -2; + } + + if (!m_signer_key.isNull()) + { + ctx->addSigningKey (m_signer_key); + } + + ctx->setTextMode (true); + ctx->setArmor (true); + + if (m_encrypt && m_sign) + { + const auto result_pair = ctx->signAndEncrypt (m_recipients, + m_input, + m_output, + GpgME::Context::AlwaysTrust); + + if (result_pair.first.error() || result_pair.second.error()) + { + log_error ("%s:%s: Encrypt / Sign error %s %s.", + SRCNAME, __func__, result_pair.first.error().asString(), + result_pair.second.error().asString()); + return -1; + } + + if (result_pair.first.error().isCanceled() || result_pair.second.error().isCanceled()) + { + log_debug ("%s:%s: User cancled", + SRCNAME, __func__); + return -2; + } + } + else if (m_encrypt) + { + const auto result = ctx->encrypt (m_recipients, m_input, + m_output, + GpgME::Context::AlwaysTrust); + if (result.error()) + { + log_error ("%s:%s: Encryption error %s.", + SRCNAME, __func__, result.error().asString()); + return -1; + } + if (result.error().isCanceled()) + { + log_debug ("%s:%s: User cancled", + SRCNAME, __func__); + return -2; + } + } + else if (m_sign) + { + const auto result = ctx->sign (m_input, m_output, + m_inline ? GpgME::Clearsigned : + GpgME::Detached); + if (result.error()) + { + log_error ("%s:%s: Signing error %s.", + SRCNAME, __func__, result.error().asString()); + return -1; + } + if (result.error().isCanceled()) + { + log_debug ("%s:%s: User cancled", + SRCNAME, __func__); + return -2; + } + } + else + { + // ??? + log_error ("%s:%s: unreachable code reached.", + SRCNAME, __func__); + } + + + log_debug ("%s:%s: Crypto done sucessfuly.", + SRCNAME, __func__); + m_crypto_success = true; return 0; } @@ -157,3 +281,21 @@ CryptController::update_mail_mapi () log_debug ("%s:%s:", SRCNAME, __func__); return 0; } + +std::string +CryptController::get_inline_data () +{ + std::string ret; + if (!m_inline) + { + return ret; + } + m_output.seek (0, SEEK_SET); + char buf[4096]; + size_t nread; + while ((nread = m_output.read (buf, 4096)) > 0) + { + ret += std::string (buf, nread); + } + return ret; +} diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h index f28c567..193c8cc 100644 --- a/src/cryptcontroller.h +++ b/src/cryptcontroller.h @@ -55,11 +55,19 @@ public: the result. */ int update_mail_mapi (); + /** @brief Get an inline body as std::string. */ + std::string get_inline_data (); + +private: + int resolve_keys (); + private: Mail *m_mail; GpgME::Data m_input, m_output; - bool m_encrypt, m_sign, m_inline; + bool m_encrypt, m_sign, m_inline, m_crypto_success; GpgME::Protocol m_proto; + GpgME::Key m_signer_key; + std::vector m_recipients; }; #endif diff --git a/src/mail.cpp b/src/mail.cpp index c0feb78..27ec8ff 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2487,12 +2487,21 @@ Mail::append_to_inline_body (const std::string &data) int Mail::inline_body_to_body() { - if (m_inline_body.empty()) + if (!m_crypter) + { + log_error ("%s:%s: No crypter.", + SRCNAME, __func__); + return -1; + } + + const auto body = m_crypter->get_inline_data (); + if (body.empty()) { return 0; } - int ret = put_oom_string (m_mailitem, "Body", m_inline_body.c_str ()); - m_inline_body = std::string(); + + int ret = put_oom_string (m_mailitem, "Body", + body.c_str ()); return ret; } @@ -2533,6 +2542,7 @@ Mail::update_crypt_oom() return; } + // We are in MIME land. Wipe the body. if (wipe (true)) { log_debug ("%s:%s: Cancel send for %p.", commit e133064eb799de9a1138f23afc5cd13d1b053fdf Author: Andre Heinecke Date: Tue Jan 30 11:59:56 2018 +0100 Continue work on async encrypt * src/mail.cpp (do_crypt): Sleep as a dummy. (Mail::update_crypt_oom): Add some code. * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Move some code to update_crypt_oom. diff --git a/src/mail.cpp b/src/mail.cpp index a48d1e2..c0feb78 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -765,6 +765,7 @@ do_crypt (LPVOID arg) /* This can take a while */ int rc = crypter->do_crypto(); + Sleep(3000); gpgrt_lock_lock (&dtor_lock); if (!Mail::is_valid_ptr (mail)) @@ -783,7 +784,7 @@ do_crypt (LPVOID arg) return rc; } - mail->set_crypt_state (Mail::NeedsUpdateInMAPI); + mail->set_crypt_state (Mail::NeedsUpdateInOOM); do_in_ui_thread (CRYPTO_DONE, arg); gpgrt_lock_unlock (&dtor_lock); @@ -2498,7 +2499,7 @@ Mail::inline_body_to_body() void Mail::update_crypt_mapi() { - log_debug ("%s:%s: Update crypt oom", + log_debug ("%s:%s: Update crypt mapi", SRCNAME, __func__); m_crypt_state = WantsSend; } @@ -2506,7 +2507,49 @@ Mail::update_crypt_mapi() void Mail::update_crypt_oom() { - log_debug ("%s:%s: Update crypt oom", - SRCNAME, __func__); + log_debug ("%s:%s: Update crypt oom for %p", + SRCNAME, __func__, this); + if (m_crypt_state != NeedsUpdateInOOM) + { + log_debug ("%s:%s: invalid state %i", + SRCNAME, __func__, m_crypt_state); + return; + } + + if (should_inline_crypt ()) + { + if (inline_body_to_body ()) + { + log_debug ("%s:%s: Inline body to body failed %p.", + SRCNAME, __func__, this); + } + } + const auto body = get_body(); + if (body.size() > 10 && !strncmp (body.c_str(), "-----BEGIN", 10)) + { + log_debug ("%s:%s: Looks like inline body. You can pass %p.", + SRCNAME, __func__, this); + m_crypt_state = NeedsSecondAfterWrite; + return; + } + + if (wipe (true)) + { + log_debug ("%s:%s: Cancel send for %p.", + SRCNAME, __func__, this); + wchar_t *title = utf8_to_wchar (_("GpgOL: Encryption not possible!")); + wchar_t *msg = utf8_to_wchar (_( + "Outlook returned an error when trying to send the encrypted mail.\n\n" + "Please restart Outlook and try again.\n\n" + "If it still fails consider using an encrypted attachment or\n" + "switching to PGP/Inline in GpgOL's options.")); + MessageBoxW (get_active_hwnd(), msg, title, + MB_ICONERROR | MB_OK); + xfree (msg); + xfree (title); + m_crypt_state = NoCryptMail; + return; + } m_crypt_state = NeedsSecondAfterWrite; + return; } diff --git a/src/mail.h b/src/mail.h index 389c6e2..8616a1e 100644 --- a/src/mail.h +++ b/src/mail.h @@ -55,6 +55,7 @@ public: NeedsActualCrypt, NeedsUpdateInOOM, NeedsSecondAfterWrite, + NeedsUpdateInMAPI, WantsSend }; @@ -373,6 +374,11 @@ public: void update_crypt_mapi (); /** Update OOM data after encryption. */ + /** Update OOM data after encryption. + + Checks for plain text leaks and + does not advance crypt state if body can't be cleaned. + */ void update_crypt_oom (); private: diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 4f1d65f..de06e47 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -357,6 +357,8 @@ EVENT_SINK_INVOKE(MailItemEvents) m_mail->update_oom_data (); m_mail->set_crypt_state (Mail::NeedsFirstAfterWrite); + log_debug ("%s:%s: Send event for crypto mail %p saving and starting.", + SRCNAME, __func__, m_mail); // Save the Mail invoke_oom_method (m_object, "Save", NULL); @@ -365,118 +367,72 @@ EVENT_SINK_INVOKE(MailItemEvents) // Cancel send *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; - } - - if (m_mail->crypt_state () == Mail::NeedsUpdateInOOM) - { - m_mail->update_crypt_oom (); + break; } if (m_mail->crypt_state () == Mail::WantsSend) { - /* Fishy behavior catcher: Sometimes the save does not clean - out the body. Weird. Happened at least for one user. - The following code checks for plain text leaks and - prevents send in case the body can't be wiped. */ - if (!m_mail->get_body().empty() || !m_mail->get_html_body().empty()) +#if 0 + /* Now we adress T3656 if Outlooks internal S/MIME is somehow + * mixed in (even if it is enabled and then disabled) it might + * cause strange behavior in that it sends the plain message + * and not the encrypted message. Tests have shown that we can + * bypass that by calling submit message on our base + * message. + * + * We do this conditionally as our other way of using OOM + * to send is proven to work and we don't want to mess + * with it. + */ + // Get the Message class. + HRESULT hr; + LPSPropValue propval = NULL; + + // It's important we use the _not_ base message here. + LPMESSAGE message = get_oom_message (m_object); + hr = HrGetOneProp ((LPMAPIPROP)message, PR_MESSAGE_CLASS_A, &propval); + gpgol_release (message); + if (FAILED (hr)) { - log_debug ("%s:%s: Body found after encryption %p.", - SRCNAME, __func__, m_object); - if (m_mail->should_inline_crypt ()) - { - if (m_mail->inline_body_to_body ()) - { - log_debug ("%s:%s: Inline body to body failed %p.", - SRCNAME, __func__, m_object); - } - } - const auto body = m_mail->get_body(); - if (body.size() > 10 && !strncmp (body.c_str(), "-----BEGIN", 10)) - { - log_debug ("%s:%s: Looks like inline body. You can pass %p.", - SRCNAME, __func__, m_object); - break; - } - - if (m_mail->wipe (true)) - { - log_debug ("%s:%s: Cancel send for %p.", - SRCNAME, __func__, m_object); - wchar_t *title = utf8_to_wchar (_("GpgOL: Encryption not possible!")); - wchar_t *msg = utf8_to_wchar (_( - "Outlook returned an error when trying to send the encrypted mail.\n\n" - "Please restart Outlook and try again.\n\n" - "If it still fails consider using an encrypted attachment or\n" - "switching to PGP/Inline in GpgOL's options.")); - MessageBoxW (get_active_hwnd(), msg, title, - MB_ICONERROR | MB_OK); - xfree (msg); - xfree (title); - *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; - return S_OK; - } - { - /* Now we adress T3656 if Outlooks internal S/MIME is somehow - * mixed in (even if it is enabled and then disabled) it might - * cause strange behavior in that it sends the plain message - * and not the encrypted message. Tests have shown that we can - * bypass that by calling submit message on our base - * message. - * - * We do this conditionally as our other way of using OOM - * to send is proven to work and we don't want to mess - * with it. - */ - // Get the Message class. - HRESULT hr; - LPSPropValue propval = NULL; - - // It's important we use the _not_ base message here. - LPMESSAGE message = get_oom_message (m_object); - hr = HrGetOneProp ((LPMAPIPROP)message, PR_MESSAGE_CLASS_A, &propval); - gpgol_release (message); - if (FAILED (hr)) - { - log_error ("%s:%s: HrGetOneProp() failed: hr=%#lx\n", - SRCNAME, __func__, hr); - gpgol_release (message); - break; - } - if (propval->Value.lpszA && !strstr (propval->Value.lpszA, "GpgOL")) - { - // Does not have a message class by us. - log_debug ("%s:%s: Message %p - No GpgOL Message class after encryption.", - SRCNAME, __func__, m_object); - log_debug ("%s:%s: Message %p - Activating T3656 Workaround", - SRCNAME, __func__, m_object); - message = get_oom_base_message (m_object); - // It's important we use the _base_ message here. - mapi_save_changes (message, KEEP_OPEN_READWRITE | FORCE_SAVE); - message->SubmitMessage(0); - gpgol_release (message); - - // Cancel send - *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; - - // Close the composer and trigger unloads - CloseHandle(CreateThread (NULL, 0, close_mail, (LPVOID) m_mail, 0, - NULL)); - } - MAPIFreeBuffer (propval); - } - - if (*(parms->rgvarg[0].pboolVal) == VARIANT_TRUE) - { - break; - } + log_error ("%s:%s: HrGetOneProp() failed: hr=%#lx\n", + SRCNAME, __func__, hr); + gpgol_release (message); + break; + } + if (propval->Value.lpszA && !strstr (propval->Value.lpszA, "GpgOL")) + { + // Does not have a message class by us. + log_debug ("%s:%s: Message %p - No GpgOL Message class after encryption.", + SRCNAME, __func__, m_object); + log_debug ("%s:%s: Message %p - Activating T3656 Workaround", + SRCNAME, __func__, m_object); + message = get_oom_base_message (m_object); + // It's important we use the _base_ message here. + mapi_save_changes (message, KEEP_OPEN_READWRITE | FORCE_SAVE); + message->SubmitMessage(0); + gpgol_release (message); + + // Cancel send + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + + // Close the composer and trigger unloads + CloseHandle(CreateThread (NULL, 0, close_mail, (LPVOID) m_mail, 0, + NULL)); + } + MAPIFreeBuffer (propval); + if (*(parms->rgvarg[0].pboolVal) == VARIANT_TRUE) + { + break; } +#endif log_debug ("%s:%s: Passing send event for message %p.", SRCNAME, __func__, m_object); break; } else { - log_debug ("%s:%s: Message %p cancelling send - crypto failed.", + log_debug ("%s:%s: Message %p cancelling send - " + "crypto or second save failed.", SRCNAME, __func__, m_object); *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } @@ -524,8 +480,6 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } - log_debug ("%s:%s: Passing write event. Subject: %s Body: %s MsgCls: %s", - SRCNAME, __func__, m_mail->get_subject().c_str(), m_mail->get_body().c_str(), get_oom_string (m_object, "MessageClass")); log_debug ("%s:%s: Passing write event.", SRCNAME, __func__); m_mail->set_needs_save (false); diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 815c217..fdb6ef0 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -98,15 +98,15 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; } // modify the mail. - if (mail->crypt_state (Mail::NeedsUpdateInOOM)) + if (mail->crypt_state () == Mail::NeedsUpdateInOOM) { + // Save the Mail + log_debug ("%s:%s: Crypto done for %p updating oom.", + SRCNAME, __func__, mail); mail->update_crypt_oom(); } - if (mail->crypt_state (Mail::NeedsSecondAfterWrite)) + if (mail->crypt_state () == Mail::NeedsSecondAfterWrite) { - // Save the Mail - log_debug ("%s:%s: Crypto done for %p Invoking second save.", - SRCNAME, __func__, mail); invoke_oom_method (mail->item (), "Save", NULL); log_debug ("%s:%s: Second save done for %p Invoking second send.", SRCNAME, __func__, mail); @@ -115,7 +115,8 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) invoke_oom_method (mail->item (), "Send", NULL); } default: - log_debug ("Unknown msg"); + log_debug ("%s:%s: Unknown msg %x", + SRCNAME, __func__, ctx->wmsg_type); } return DefWindowProc(hWnd, message, wParam, lParam); } ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 142 +++++++++++++++++++++++++++++++++++++++++++ src/cryptcontroller.h | 10 ++- src/mail.cpp | 67 +++++++++++++++++--- src/mail.h | 6 ++ src/mailitem-events.cpp | 158 +++++++++++++++++------------------------------- src/windowmessages.cpp | 13 ++-- 6 files changed, 280 insertions(+), 116 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 30 15:21:29 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 30 Jan 2018 15:21:29 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-5-gf622470 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via f622470a3a291cd8d39e9dc45fa5d6496e66089d (commit) from e789048f47fccab444df477f6e82ece69fa2a8b4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f622470a3a291cd8d39e9dc45fa5d6496e66089d Author: Andre Heinecke Date: Tue Jan 30 15:17:48 2018 +0100 Make MIME encrypt work in the new way * src/cryptcontroller.cpp (CryptController::update_mail_mapi): Do actual update. (create_encrypt_attach): Helper to set up the right attachment. (write_data): Helper to write GpgME::Data to a sink. * src/mail.cpp (Mail::update_crypt_mapi): Call update_mail_mapi. * src/mimemaker.cpp, src/mimemaker.h: Export some more helpers. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index ebb18bb..c950cdf 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -275,11 +275,127 @@ CryptController::do_crypto () return 0; } +static int +write_data (sink_t sink, GpgME::Data &data) +{ + if (!sink || !sink->writefnc) + { + return -1; + } + + char buf[4096]; + size_t nread; + data.seek (0, SEEK_SET); + while ((nread = data.read (buf, 4096)) > 0) + { + sink->writefnc (sink, buf, nread); + } + + return 0; +} + +static int +create_encrypt_attach (sink_t sink, protocol_t protocol, + GpgME::Data &encryptedData) +{ + char boundary[BOUNDARYSIZE+1]; + int rc = create_top_encryption_header (sink, protocol, boundary, + false); + // From here on use goto failure pattern. + if (rc) + { + log_error ("%s:%s: Failed to create top header.", + SRCNAME, __func__); + return rc; + } + + rc = write_data (sink, encryptedData); + if (rc) + { + log_error ("%s:%s: Failed to create top header.", + SRCNAME, __func__); + return rc; + } + + /* Write the final boundary (for OpenPGP) and finish the attachment. */ + if (*boundary && (rc = write_boundary (sink, boundary, 1))) + { + log_error ("%s:%s: Failed to write boundary.", + SRCNAME, __func__); + } + return rc; +} + int CryptController::update_mail_mapi () { log_debug ("%s:%s:", SRCNAME, __func__); - return 0; + + if (m_inline) + { + // Nothing to do for inline. + return 0; + } + + LPMESSAGE message = get_oom_base_message (m_mail->item()); + if (!message) + { + log_error ("%s:%s: Failed to obtain message.", + SRCNAME, __func__); + return -1; + } + + mapi_attach_item_t *att_table = mapi_create_attach_table (message, 0); + + // Set up the sink object for our MSOXSMIME attachment. + struct sink_s sinkmem; + sink_t sink = &sinkmem; + memset (sink, 0, sizeof *sink); + sink->cb_data = &m_input; + sink->writefnc = sink_data_write; + + LPATTACH attach = create_mapi_attachment (message, sink); + if (!attach) + { + log_error ("%s:%s: Failed to create moss attach.", + SRCNAME, __func__); + gpgol_release (message); + return -1; + } + + protocol_t protocol = m_proto == GpgME::CMS ? + PROTOCOL_SMIME : + PROTOCOL_OPENPGP; + int rc = 0; + if (m_encrypt) + { + rc = create_encrypt_attach (sink, protocol, m_output); + } + + // Close our attachment + if (!rc) + { + rc = close_mapi_attachment (&attach, sink); + } + + // Set message class etc. + if (!rc) + { + rc = finalize_message (message, att_table, protocol, 1, false); + } + + // only on error. + if (rc) + { + cancel_mapi_attachment (&attach, sink); + } + + // cleanup + mapi_release_attach_table (att_table); + gpgol_release (attach); + gpgol_release (message); + + return rc; } std::string diff --git a/src/mail.cpp b/src/mail.cpp index 27ec8ff..0b270e0 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2510,7 +2510,32 @@ Mail::update_crypt_mapi() { log_debug ("%s:%s: Update crypt mapi", SRCNAME, __func__); - m_crypt_state = WantsSend; + if (m_crypt_state != NeedsUpdateInMAPI) + { + log_debug ("%s:%s: invalid state %i", + SRCNAME, __func__, m_crypt_state); + return; + } + if (!m_crypter) + { + log_error ("%s:%s: No crypter.", + SRCNAME, __func__); + m_crypt_state = NoCryptMail; + return; + } + + if (m_crypter->update_mail_mapi ()) + { + log_error ("%s:%s: Failed to update MAPI after crypt", + SRCNAME, __func__); + m_crypt_state = NoCryptMail; + } + else + { + m_crypt_state = WantsSend; + } + // We don't need the crypter anymore. + m_crypter = nullptr; } void diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index 1f9de4e..d638fb2 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -152,7 +152,7 @@ check_protocol (protocol_t protocol) to is stored at STREAM and the attachment object itself is returned. The caller needs to call SaveChanges. Returns NULL on failure in which case STREAM will be set to NULL. */ -static LPATTACH +LPATTACH create_mapi_attachment (LPMESSAGE message, sink_t sink) { HRESULT hr; @@ -304,7 +304,7 @@ write_multistring (sink_t sink, const char *text1, ...) /* Helper to write a boundary to the output sink. The leading LF will be written as well. */ -static int +int write_boundary (sink_t sink, const char *boundary, int lastone) { int rc = write_string (sink, "\r\n--"); @@ -1084,7 +1084,7 @@ delete_all_attachments (LPMESSAGE message, mapi_attach_item_t *table) SINK needs to be passed as well and will also be closed. Note that the address of ATTACH is expected so that the fucntion can set it to NULL. */ -static int +int close_mapi_attachment (LPATTACH *attach, sink_t sink) { HRESULT hr; @@ -1121,7 +1121,7 @@ close_mapi_attachment (LPATTACH *attach, sink_t sink) SINK needs to be passed as well and will also be closed. Note that the address of ATTACH is expected so that the fucntion can set it to NULL. */ -static void +void cancel_mapi_attachment (LPATTACH *attach, sink_t sink) { LPSTREAM stream = sink ? (LPSTREAM) sink->cb_data : NULL; @@ -1143,9 +1143,9 @@ cancel_mapi_attachment (LPATTACH *attach, sink_t sink) /* Do the final processing for a message. */ -static int +int finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table, - protocol_t protocol, int encrypt, bool is_inline = false) + protocol_t protocol, int encrypt, bool is_inline) { HRESULT hr = 0; SPropValue prop; @@ -1883,9 +1883,9 @@ sink_encryption_write_b64 (sink_t encsink, const void *data, size_t datalen) /* Helper from mime_encrypt. BOUNDARY is a buffer of at least BOUNDARYSIZE+1 bytes which will be set on return from that function. */ -static int +int create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary, - bool is_inline = false) + bool is_inline) { int rc; diff --git a/src/mimemaker.h b/src/mimemaker.h index 2896a60..cbf83a8 100644 --- a/src/mimemaker.h +++ b/src/mimemaker.h @@ -76,6 +76,20 @@ int count_usable_attachments (mapi_attach_item_t *table); int add_body_and_attachments (sink_t sink, LPMESSAGE message, mapi_attach_item_t *att_table, Mail *mail, const char *body, int n_att_usable); +int create_top_encryption_header (sink_t sink, protocol_t protocol, char *boundary, + bool is_inline = false); + +/* Helper to write a boundary to the output sink. The leading LF + will be written as well. */ +int write_boundary (sink_t sink, const char *boundary, int lastone); + +LPATTACH create_mapi_attachment (LPMESSAGE message, sink_t sink); +int close_mapi_attachment (LPATTACH *attach, sink_t sink); +int finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table, + protocol_t protocol, int encrypt, bool is_inline = false); +void cancel_mapi_attachment (LPATTACH *attach, sink_t sink); + + #ifdef __cplusplus } #endif ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++++++- src/mail.cpp | 27 ++++++++++- src/mimemaker.cpp | 16 +++---- src/mimemaker.h | 14 ++++++ 4 files changed, 165 insertions(+), 10 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 30 15:51:28 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 30 Jan 2018 15:51:28 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-6-gc52f7ed Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via c52f7ed9456ad1db74b09bc1eae32750b4277fee (commit) from f622470a3a291cd8d39e9dc45fa5d6496e66089d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c52f7ed9456ad1db74b09bc1eae32750b4277fee Author: Andre Heinecke Date: Tue Jan 30 15:49:26 2018 +0100 Implement MIME Sign in the new way * src/cryptcontroller.cpp (create_sign_attach): New. (CryptController::update_mail_mapi): Handle sign only. * src/mimemaker.h, src/mimemaker.cpp: Expose more functions. * src/mail.cpp (do_crypt): Remove sleep ;-) diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index c950cdf..2d14038 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -295,6 +295,103 @@ write_data (sink_t sink, GpgME::Data &data) } static int +create_sign_attach (sink_t sink, protocol_t protocol, + GpgME::Data &signature, + GpgME::Data &signedData) +{ + char boundary[BOUNDARYSIZE+1]; + char top_header[BOUNDARYSIZE+200]; + int rc = 0; + + /* Write the top header. */ + generate_boundary (boundary); + create_top_signing_header (top_header, sizeof top_header, + protocol, 1, boundary, + protocol == PROTOCOL_SMIME ? "sha1":"pgp-sha1"); + + if ((rc = write_string (sink, top_header))) + { + TRACEPOINT; + return rc; + } + + /* Write the boundary so that it is not included in the hashing. */ + if ((rc = write_boundary (sink, boundary, 0))) + { + TRACEPOINT; + return rc; + } + + /* Write the signed mime structure */ + if ((rc = write_data (sink, signedData))) + { + TRACEPOINT; + return rc; + } + + /* Write the signature attachment */ + if ((rc = write_boundary (sink, boundary, 0))) + { + TRACEPOINT; + return rc; + } + + if (protocol == PROTOCOL_OPENPGP) + { + rc = write_string (sink, + "Content-Type: application/pgp-signature\r\n"); + } + else + { + rc = write_string (sink, + "Content-Transfer-Encoding: base64\r\n" + "Content-Type: application/pkcs7-signature\r\n"); + /* rc = write_string (sink, */ + /* "Content-Type: application/x-pkcs7-signature\r\n" */ + /* "\tname=\"smime.p7s\"\r\n" */ + /* "Content-Transfer-Encoding: base64\r\n" */ + /* "Content-Disposition: attachment;\r\n" */ + /* "\tfilename=\"smime.p7s\"\r\n"); */ + + } + + if (rc) + { + TRACEPOINT; + return rc; + } + + if ((rc = write_string (sink, "\r\n"))) + { + TRACEPOINT; + return rc; + } + + // Write the signature data + if ((rc = write_data (sink, signature))) + { + TRACEPOINT; + return rc; + } + + // Add an extra linefeed with should not harm. + if ((rc = write_string (sink, "\r\n"))) + { + TRACEPOINT; + return rc; + } + + /* Write the final boundary. */ + if ((rc = write_boundary (sink, boundary, 1))) + { + TRACEPOINT; + return rc; + } + + return rc; +} + +static int create_encrypt_attach (sink_t sink, protocol_t protocol, GpgME::Data &encryptedData) { @@ -367,10 +464,19 @@ CryptController::update_mail_mapi () PROTOCOL_SMIME : PROTOCOL_OPENPGP; int rc = 0; - if (m_encrypt) + if (m_sign && m_encrypt) { + // FIXME we need some doubling here for S/MIME. rc = create_encrypt_attach (sink, protocol, m_output); } + else if (m_encrypt) + { + rc = create_encrypt_attach (sink, protocol, m_output); + } + else if (m_sign) + { + rc = create_sign_attach (sink, protocol, m_output, m_input); + } // Close our attachment if (!rc) @@ -381,7 +487,8 @@ CryptController::update_mail_mapi () // Set message class etc. if (!rc) { - rc = finalize_message (message, att_table, protocol, 1, false); + rc = finalize_message (message, att_table, protocol, m_encrypt ? 1 : 0, + false); } // only on error. diff --git a/src/mail.cpp b/src/mail.cpp index 0b270e0..53f2890 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -765,7 +765,6 @@ do_crypt (LPVOID arg) /* This can take a while */ int rc = crypter->do_crypto(); - Sleep(3000); gpgrt_lock_lock (&dtor_lock); if (!Mail::is_valid_ptr (mail)) diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index d638fb2..2693f49 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -273,7 +273,7 @@ write_buffer_for_cb (void *opaque, const void *data, size_t datalen) /* Write the string TEXT to the IStream STREAM. Returns 0 on sucsess, prints an error message and returns -1 on error. */ -static int +int write_string (sink_t sink, const char *text) { return write_buffer (sink, text, strlen (text)); @@ -1298,7 +1298,7 @@ collect_signature (void *opaque, const void *data, size_t datalen) /* Helper to create the signing header. This includes enough space for later fixup of the micalg parameter. The MIME version is only written if FIRST is set. */ -static void +void create_top_signing_header (char *buffer, size_t buflen, protocol_t protocol, int first, const char *boundary, const char *micalg) { diff --git a/src/mimemaker.h b/src/mimemaker.h index cbf83a8..3f29ecc 100644 --- a/src/mimemaker.h +++ b/src/mimemaker.h @@ -88,7 +88,9 @@ int close_mapi_attachment (LPATTACH *attach, sink_t sink); int finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table, protocol_t protocol, int encrypt, bool is_inline = false); void cancel_mapi_attachment (LPATTACH *attach, sink_t sink); - +void create_top_signing_header (char *buffer, size_t buflen, protocol_t protocol, + int first, const char *boundary, const char *micalg); +int write_string (sink_t sink, const char *text); #ifdef __cplusplus } ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++- src/mail.cpp | 1 - src/mimemaker.cpp | 4 +- src/mimemaker.h | 4 +- 4 files changed, 114 insertions(+), 6 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 31 13:23:12 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 31 Jan 2018 13:23:12 +0100 Subject: [git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-9-g26b9319 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, async-enc has been updated via 26b931937fe139a9acd3240242e154d3789652f5 (commit) via 3ed205e7f9d96edfa03762c8692267f68d82ebb8 (commit) via ee673d23ae83563faabe5168019092203766e670 (commit) from c52f7ed9456ad1db74b09bc1eae32750b4277fee (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 26b931937fe139a9acd3240242e154d3789652f5 Author: Andre Heinecke Date: Wed Jan 31 13:20:26 2018 +0100 Fix inline responses by making them sync * src/mail.cpp (Mail::is_inline_response), (Mail::check_inline_response): New. (do_crypt): Work sync for inline response. * src/mailitem-events.cpp: Work sync for inline response. -- Its nice how we can switch between sync and async in the new architecture. Hopefully this does not mean double bugs ;-) Working sync for inline response is necessary because we can't trigger a send event programatically for inline responses. diff --git a/src/mail.cpp b/src/mail.cpp index 11c31a3..e9000f2 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -138,7 +138,8 @@ Mail::Mail (LPDISPATCH mailitem) : m_do_inline(false), m_is_gsuite(false), m_crypt_state(NoCryptMail), - m_window(nullptr) + m_window(nullptr), + m_is_inline_response(false) { if (get_mail_for_item (mailitem)) { @@ -785,9 +786,17 @@ do_crypt (LPVOID arg) return rc; } - mail->set_crypt_state (Mail::NeedsUpdateInOOM); - - do_in_ui_thread (CRYPTO_DONE, arg); + if (!mail->is_inline_response ()) + { + mail->set_crypt_state (Mail::NeedsUpdateInOOM); + do_in_ui_thread (CRYPTO_DONE, arg); + } + else + { + mail->set_crypt_state (Mail::NeedsUpdateInMAPI); + mail->update_crypt_mapi (); + mail->set_crypt_state (Mail::NeedsUpdateInOOM); + } gpgrt_lock_unlock (&dtor_lock); return 0; } @@ -1157,9 +1166,17 @@ Mail::encrypt_sign_start () SRCNAME, __func__, this); return -1; } - CloseHandle(CreateThread (NULL, 0, do_crypt, - (LPVOID) this, 0, - NULL)); + + if (!m_is_inline_response) + { + CloseHandle(CreateThread (NULL, 0, do_crypt, + (LPVOID) this, 0, + NULL)); + } + else + { + do_crypt (this); + } return 0; } @@ -2601,3 +2618,49 @@ Mail::set_window_enabled (bool value) EnableWindow (m_window, value ? TRUE : FALSE); } + +bool +Mail::check_inline_response () +{ + m_is_inline_response = false; + LPDISPATCH app = GpgolAddin::get_instance ()->get_application (); + if (!app) + { + TRACEPOINT; + return false; + } + + LPDISPATCH explorer = get_oom_object (app, "ActiveExplorer"); + + if (!explorer) + { + TRACEPOINT; + return false; + } + + LPDISPATCH inlineResponse = get_oom_object (explorer, "ActiveInlineResponse"); + gpgol_release (explorer); + + if (!inlineResponse) + { + return false; + } + + // We have inline response + // Check if we are it. It's a bit naive but meh. Worst case + // is that we think inline response too often and do sync + // crypt where we could do async crypt. + char * inlineSubject = get_oom_string (inlineResponse, "Subject"); + gpgol_release (inlineResponse); + + const auto subject = get_subject (); + if (inlineResponse && !subject.empty() && !strcmp (subject.c_str (), inlineSubject)) + { + log_debug ("%s:%s: Detected inline response for '%p'", + SRCNAME, __func__, this); + m_is_inline_response = true; + } + xfree (inlineSubject); + + return m_is_inline_response; +} diff --git a/src/mail.h b/src/mail.h index 0b03ed9..ef0f353 100644 --- a/src/mail.h +++ b/src/mail.h @@ -387,6 +387,22 @@ public: enable. */ void set_window_enabled (bool value); + /** Determine if the mail is an inline response. + + Call check_inline_response first to update the state + from the OOM. + + We need synchronous encryption for inline responses. */ + bool is_inline_response () { return m_is_inline_response; } + + /** Check through OOM if the current mail is an inline + response. + + Caches the state which can then be queried through + is_inline_response + */ + bool check_inline_response (); + private: void update_categories (); void update_body (); @@ -425,5 +441,6 @@ private: std::string m_inline_body; CryptState m_crypt_state; HWND m_window; + bool m_is_inline_response; }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 7023ba7..ec38046 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -358,17 +358,35 @@ EVENT_SINK_INVOKE(MailItemEvents) m_mail->set_window_enabled (false); m_mail->set_crypt_state (Mail::NeedsFirstAfterWrite); + // Check inline response state before the write. + m_mail->check_inline_response (); + log_debug ("%s:%s: Send event for crypto mail %p saving and starting.", SRCNAME, __func__, m_mail); // Save the Mail invoke_oom_method (m_object, "Save", NULL); - // The afterwrite in the save should have triggered - // the encryption. We cancel send for our asyncness. - - // Cancel send - *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; - break; + if (!m_mail->is_inline_response ()) + { + // The afterwrite in the save should have triggered + // the encryption. We cancel send for our asyncness. + // Cancel send + *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; + break; + } + else + { + // For inline response we can't trigger send programatically + // so we do the encryption in sync. + if (m_mail->crypt_state () == Mail::NeedsUpdateInOOM) + { + m_mail->update_crypt_oom (); + } + if (m_mail->crypt_state () == Mail::NeedsSecondAfterWrite) + { + m_mail->set_crypt_state (Mail::WantsSend); + } + } } if (m_mail->crypt_state () == Mail::WantsSend) commit 3ed205e7f9d96edfa03762c8692267f68d82ebb8 Author: Andre Heinecke Date: Wed Jan 31 11:37:32 2018 +0100 Reactivate T3656 workaround * src/mailitem-events.cpp: Reactivate workaround. -- Now that we do real encryption we can activate this hack again. diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index f4b9cac..7023ba7 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -373,7 +373,6 @@ EVENT_SINK_INVOKE(MailItemEvents) if (m_mail->crypt_state () == Mail::WantsSend) { -#if 0 /* Now we adress T3656 if Outlooks internal S/MIME is somehow * mixed in (even if it is enabled and then disabled) it might * cause strange behavior in that it sends the plain message @@ -425,7 +424,6 @@ EVENT_SINK_INVOKE(MailItemEvents) { break; } -#endif log_debug ("%s:%s: Passing send event for message %p.", SRCNAME, __func__, m_object); break; commit ee673d23ae83563faabe5168019092203766e670 Author: Andre Heinecke Date: Wed Jan 31 11:28:43 2018 +0100 Fix window modality of encryption * src/mail.cpp: Add new member m_window. (do_crypt): Renable window when done. (Mail::set_window_enabled): New. * src/mail.h: Update accordingly. * src/mailitem-events.cpp: Disable mail window on crypt send. * src/oomhelp.cpp (get_active_hwnd): Add some fallbacks. diff --git a/src/mail.cpp b/src/mail.cpp index 53f2890..11c31a3 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -137,7 +137,8 @@ Mail::Mail (LPDISPATCH mailitem) : m_type(MSGTYPE_UNKNOWN), m_do_inline(false), m_is_gsuite(false), - m_crypt_state(NoCryptMail) + m_crypt_state(NoCryptMail), + m_window(nullptr) { if (get_mail_for_item (mailitem)) { @@ -763,7 +764,6 @@ do_crypt (LPVOID arg) return -1; } - /* This can take a while */ int rc = crypter->do_crypto(); gpgrt_lock_lock (&dtor_lock); @@ -775,6 +775,8 @@ do_crypt (LPVOID arg) return 0; } + mail->set_window_enabled (true); + if (rc) { log_debug ("%s:%s: crypto failed for: %p with: %i", @@ -1155,7 +1157,6 @@ Mail::encrypt_sign_start () SRCNAME, __func__, this); return -1; } - //EnableWindow (window, FALSE); CloseHandle(CreateThread (NULL, 0, do_crypt, (LPVOID) this, 0, NULL)); @@ -2587,3 +2588,16 @@ Mail::update_crypt_oom() m_crypt_state = NeedsSecondAfterWrite; return; } + +void +Mail::set_window_enabled (bool value) +{ + if (!value) + { + m_window = get_active_hwnd (); + } + log_debug ("%s:%s: enable window %p %i", + SRCNAME, __func__, m_window, value); + + EnableWindow (m_window, value ? TRUE : FALSE); +} diff --git a/src/mail.h b/src/mail.h index 8616a1e..0b03ed9 100644 --- a/src/mail.h +++ b/src/mail.h @@ -373,7 +373,6 @@ public: /** Update MAPI data after encryption. */ void update_crypt_mapi (); - /** Update OOM data after encryption. */ /** Update OOM data after encryption. Checks for plain text leaks and @@ -381,6 +380,13 @@ public: */ void update_crypt_oom (); + /** Enable / Disable the window of this mail. + + When value is false the active window will + be disabled and the handle stored for a later + enable. */ + void set_window_enabled (bool value); + private: void update_categories (); void update_body (); @@ -418,5 +424,6 @@ private: bool m_is_gsuite; /* Are we on a gsuite account */ std::string m_inline_body; CryptState m_crypt_state; + HWND m_window; }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index de06e47..f4b9cac 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -355,10 +355,11 @@ EVENT_SINK_INVOKE(MailItemEvents) // First contact with a mail to encrypt update // state and oom data. m_mail->update_oom_data (); + m_mail->set_window_enabled (false); m_mail->set_crypt_state (Mail::NeedsFirstAfterWrite); - log_debug ("%s:%s: Send event for crypto mail %p saving and starting.", - SRCNAME, __func__, m_mail); + log_debug ("%s:%s: Send event for crypto mail %p saving and starting.", + SRCNAME, __func__, m_mail); // Save the Mail invoke_oom_method (m_object, "Save", NULL); diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index 45013b4..ce444d7 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -1749,8 +1749,16 @@ get_active_hwnd () LPDISPATCH activeWindow = get_oom_object (app, "ActiveWindow"); if (!activeWindow) { - TRACEPOINT; - return nullptr; + activeWindow = get_oom_object (app, "ActiveInspector"); + if (!activeWindow) + { + activeWindow = get_oom_object (app, "ActiveExplorer"); + if (!activeWindow) + { + TRACEPOINT; + return nullptr; + } + } } /* Both explorer and inspector have this. */ ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++----- src/mail.h | 26 +++++++++++++- src/mailitem-events.cpp | 37 +++++++++++++------ src/oomhelp.cpp | 12 +++++-- 4 files changed, 148 insertions(+), 22 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org