Closed Bug 1659443 Opened 4 years ago Closed 4 years ago

Use JS API readTypedArray() to fix slow OpenPGP decryption

Categories

(MailNews Core :: Security: OpenPGP, defect)

defect

Tracking

(thunderbird_esr78+ fixed, thunderbird81 wontfix)

RESOLVED FIXED
82 Branch
Tracking Status
thunderbird_esr78 + fixed
thunderbird81 --- wontfix

People

(Reporter: KaiE, Assigned: KaiE)

References

Details

Attachments

(2 files, 1 obsolete file)

Processing a 7 MB encrypted message takes 40 seconds on a fast computer.

(Timing is for a debug build, updated timing info in comment 3.)

The slow part is this loop, which converts from a js-ctypes byte array to a JS string:
https://searchfox.org/comm-central/rev/38c93f8c99cfe10cff5cd1b0ce399ff2334c0003/mail/extensions/openpgp/content/modules/RNP.jsm#973

Is there a more efficient way to perform this conversion?

This is fast:

        let char_array = ctypes.cast(
          result_buf,
          ctypes.char.array(result_len.value).ptr
        ).contents;

        result.decryptedData = char_array.readString();

... but we cannot use it. If the decryptedData contains a message with 8-bit characters in an encoding other than UTF-8, then readString() fails. And using readStringReplaceMalformed() would result in dataloss.

Help wanted from a js-ctypes expert.
Whom could we ask?

Flags: needinfo?(mkmelin+mozilla)

(In reply to Kai Engert (:KaiE:) from comment #0)

Processing a 7 MB encrypted message takes 40 seconds on a fast computer.

Well, this was for a debug build.
With a fully optimized build, it's about 5 seconds for this loop.

Sorry, I don't know who would know about js-ctypes. Could ask in #developers?

Some thoughts:
Is that an Uint8Array, or what is the real type?
Could we use something like new TextDecoder("utf-8").decode(Uint8Array.from(uint8_array));

But then again, if it's not UTF-8, how will you know what to decode it to?

Flags: needinfo?(mkmelin+mozilla)

The source of the problem is that it's not a UTF-8 string. That conversion is not allowed. You have to interpret it as binary 8-bit data stored in a string.

(In reply to Magnus Melin [:mkmelin] from comment #4)

Is that an Uint8Array, or what is the real type?

No, this is the type:

      let result_buf = new ctypes.uint8_t.ptr();
Depends on: 1659508

Patrick, for MIME messages, if they are in non-UTF-8 encodings, do you think we might ever see NULL bytes?

Steve has thankfully worked on a new JS String API that might help us to obtain the data in an efficient way, but it would terminate at NULL.

Flags: needinfo?(patrick)
Attached patch 1659443-v1.patch (obsolete) — Splinter Review

This patch uses the suggested new API from bug 1659508.

It works for me and is fast.

Once bug 1659508 is reviewed, we could consider to start using a THUNDERBIRD_78_VERBRANCH of mozilla-esr78 and apply it locally. (It seems unlikely that Mozilla would accept the patch for mozilla-esr78, but we could ask, once ready.)

Magnus, Wayne, any thoughts on starting a THUNDERBIRD_78_VERBRANCH for mozilla-esr78 ?

I have no objection. I defer to Magnus and Rob.

I'd like to discuss this further in a Zoom if possible and bring in Ryan V if since it's likely him that would be maintaining this branch.

I think that NULL bytes are not allowed in MIME strings.

Flags: needinfo?(patrick)
Depends on: 1659801

(In reply to Rob Lemley [:rjl] from comment #11)

I'd like to discuss this further in a Zoom if possible and bring in Ryan V if since it's likely him that would be maintaining this branch.

What do you need to push this forward?

Attachment #9170681 - Attachment is obsolete: true

I have tested the final code from bug 1659801, locally applied to mozilla-esr78.
It works fine.
I'll attach a phabricator patch that makes use of the feature.

The open question is, how can we take this patch for Thunderbird 78.x ?

I've asked for uplift of the new feature to the official mozilla-esr78 branch.
Should this request get rejected, then we cannot avoid our own THUNDERBIRD_78_VERBRANCH.

Summary: Processing an OpenPGP message is very slow → Backport and use JS API readTypedArray() to fix slow OpenPGP decryption
Summary: Backport and use JS API readTypedArray() to fix slow OpenPGP decryption → Use JS API readTypedArray() to fix slow OpenPGP decryption

Thankfully the required JS API has been applied to mozilla-esr78.

Attached patch 1659443.patchSplinter Review

same patch as latest rev in phab

Pushed by geoff@darktrojan.net:
https://hg.mozilla.org/comm-central/rev/2de738db85be
Use js-ctypes readTypedArray() from bug 1659801 for faster decryption. r=mkmelin

Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → 82 Branch

Magnus had requested to change another place, I had missed that request, sorry.
Will create a follow-up patch.

(In reply to Kai Engert (:KaiE:) from comment #19)

Magnus had requested to change another place, I had missed that request, sorry.
Will create a follow-up patch.

Unfortunately it isn't working in the other place!
This isn't a blocker, I've filed it as bug 1663339.

See Also: → 1663339

I see that 78.3.0 has been pinned to comm-esr78, this means we're ready to uplift this fix.

Comment on attachment 9172493 [details]
Bug 1659443 - Use js-ctypes readTypedArray() from bug 1659801 for faster decryption. r=mkmelin

[Approval Request Comment]
Regression caused by (bug #): none
User impact if declined: much slowness decrypting big messages
Testing completed (on c-c, etc.): yes
Risk to taking this patch (and alternatives if risky): low, any problem would be immediately obvious

Attachment #9172493 - Flags: approval-comm-esr78?

Comment on attachment 9172493 [details]
Bug 1659443 - Use js-ctypes readTypedArray() from bug 1659801 for faster decryption. r=mkmelin

[Triage Comment]
Approved for esr78 - if Rob can take it

Attachment #9172493 - Flags: approval-comm-esr78? → approval-comm-esr78+
Regressions: 1665287
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: