PKCS#12 PBE doesn't convert to UTF-16BE correctly #337
Labels
No labels
api-spec
bug
CLA requested
CLA valid
compliance
DO NOT MERGE
duplicate
enhancement
feature branch
good first issue
HEADER FORMATTING ISSUE
help wanted
Information
invalid
Jira status: AWAITING REVIEW
Jira status: CLOSED
Jira status: DONE
Jira status: IN PROGRESS
Jira status: IN REVIEW
Jira status: OPEN
Jira status: REOPENED
Jira status: RESOLVED
mirrored
mirror internally
needs: backports
needs: ci
needs: design review
needs: preceding PR
needs: review
needs: work
notabug
open for community contribution
Product Backlog
question
ready for merge
security
stale
type: bug
type: enhancement
type: question
web pages
wontfix
writing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-ARMmbed/mbed-crypto#337
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
See https://github.com/magnumripper/JohnTheRipper/issues/4179
The PKCS#12 PBE function cheats when "converting" to UTF-16BE. It simply casts char -> short, or "inserts every other zero". While this happens to be correct for ISO-8859-1, it's not for the remaining 99.8% of the Unicode charset or 99.5% of UCS-2.
Actually, as far as I can see, these functions can't ever take a "string" as input unless they also take a parameter describing the encoding of it (that, or requiring a certain encoding - which should probably be UTF-8 for guaranteeing full functionality) because otherwise you simply can't know how to convert it properly. Most other functions take binary data and length and then the caller can decide to convert [correctly] to UTF-16BE before calling them.
A super-quick "workaround" would be to clearly document that the function only work correctly for ASCII and ISO-8859-1. But then you wouldn't be compatible with libs that do it right.
This bug is particularly bad in that if you, say, encrypt a certificate on a system using mbedTLS and then try to decrypt it on a system without this bug, your password won't work. Or vice versa. We are seeing examples of this.
(See below)
Please note that I haven't yet checked how OpenSSL handles this. I wouldn't be too surprised if they do the same, and in that case you are bug compatible with them.The software we've seen so far that does the correct conversion happens to be running on Windows.
Internal Jira reference: https://jira.arm.com/browse/IOTCRYPT-1032
Apparently OpenSSL doesn't have this bug if used correctly: It has functions like
OPENSSL_asc2uni()which works just like your code but it also hasOPENSSL_utf82uni()and as long as the latter is used, caller is bug free in this aspect. The UTF-8 functions were added in November 2015.Edit:
https://mta.openssl.org/pipermail/openssl-dev/2016-August/008371.html
Mbed TLS mostly focuses on embedded devices where code size is at a premium and non-ASCII character encodings are rarely used, and we try to avoid breaking backward compatibility. So I favor:
pkcs12_pbe_derive_key_ivexpects its argumentpwdto be encoded in latin1.wchar_t? (Would create a dependency on that type, which freestanding C implementations might not have.)uint16_t? (Would this be useful in practice?) And should it be documented as taking a BMPString per RFC 7292 or UTF-16 (allowing characters outside the basic plane)?