Firmware Key and Signature Formats: Difference between revisions
(Initial import of Noah's email.) |
|||
(23 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
{{translations}} |
|||
Key |
|||
=== |
|||
This page describes the key and signature formats understood by OFW. The [[Firmware Security]] page describes how these are used. |
|||
key01 alg datalen data\n |
|||
3 2 1 3 1 3 1 N 1 |
|||
==Key== |
|||
So thats: |
|||
* the literal string "key" |
|||
* the two digit version number ("01" for now) |
|||
* a space |
|||
* the three character algorithm name (for now this will always be |
|||
"rsa") |
|||
* a space |
|||
* the three digit length for the key data |
|||
* a space |
|||
* the key data as a hex-encoded string |
|||
* a newline |
|||
key01: data\n |
|||
Signature |
|||
3 2 2 N 1 |
|||
========= |
|||
So that's: |
|||
sig01 timestamp keyid datalen data\n |
|||
* The literal string "key" |
|||
3 2 1 12 1 64 1 3 1 N 1 |
|||
* The two digit version number ("01" for now) |
|||
* A colon |
|||
* A space |
|||
* The key data |
|||
* A newline |
|||
The key data is a hexadecimal-encoded octet string. The octet string is the ASN.1 DER encoding of an RSA public key given by Appendix A.1.1 of [ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf RSA PKCS #1, version 2.1]. |
|||
So thats: |
|||
* the literal string "sig" |
|||
Future versions of the key format might allow different algorithms. |
|||
* the two digit version number ("01" for now) |
|||
* a space |
|||
==Signature== |
|||
* the 12 character timestamp (ex., "200708161735" -> 2007-07-08 |
|||
===Version 1=== |
|||
16:17:35) |
|||
sig01: hashname keyid data\n |
|||
* a space |
|||
3 2 2 6 1 64 1 N 1 |
|||
* the 64 character key ID, as a hex-encoded SHA256 hash of the key |
|||
file (for the immediate future you can ignore this in the firmware, |
|||
So that's: |
|||
and just use a single key for each task.) |
|||
* The literal string "sig" |
|||
* a space |
|||
* The two digit version number ("01" for now) |
|||
* A colon |
|||
* A space |
|||
* the signature data as a hex-encoded string |
|||
* A six character name for the hash function used by this signature |
|||
* a newline |
|||
** "sha256" indicates that this is an RSASSA-PSS signature using SHA256 as the hash and MGF1-SHA256 as the mask function. |
|||
** "rmd160" indicates that this is an RSASSA-PKCS1-v1_5 signature using RIPEMD-160 as the hash function. |
|||
* A space |
|||
* The 64 character key ID, which are the trailing 64 characters of the "key data" in the key format above. (for the immediate future you can ignore this in the firmware, and just use a single key for each task.) |
|||
** This includes the exponent and the least significant bytes of the modulus |
|||
* A space |
|||
* The signature data as a hexadecimal-encoded string. The encoded data is the octet string given by section 8.1.1/8.2.1 of [ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf RSA PKCS #1, version 2.1]. |
|||
* A newline |
|||
===Version 2=== |
|||
Version 2 signatures are (a) delegated, (b) tied to a particular serial number, and (c) may expire. The format is: |
|||
sig02: hashname_1 key-or-keyid_1 expiration_1 data_1 hashname_2 ...\n |
|||
3 2 2 6 1 N/64 1 16 1 M 1 ... 1 |
|||
The "hashname key expiration data" section is repeated as many |
|||
times as there are signatures in the chain. We will call each |
|||
repetition an 'sg' below. So the contents of a sig02 are: |
|||
* The literal string "sig" |
|||
* The two digit version number ("02") |
|||
* A colon |
|||
* A space |
|||
At least one sg, consisting of: |
|||
* A six character name for the hash function used by this signature |
|||
** "sha256" indicates that this is an RSASSA-PSS signature using SHA256 as the hash and MGF1-SHA256 as the mask function. |
|||
** "rmd160" indicates that this is an RSASSA-PKCS1-v1_5 signature using RIPEMD-160 as the hash function. |
|||
* A space |
|||
* At least 64 characters of key data in the key01 format. The characters must be a suffix of the full key data; if more than 64 characters are present they are assumed to be the full key. |
|||
** 64 characters is sufficient to include the exponent and the least significant bytes of the modulus |
|||
** it is recommended that only keyid_1 be abbreviated. |
|||
* A space |
|||
* An ISO 8601 UTC expiration time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z"). After this time, the sg must no longer be considered valid. |
|||
** The string "00000000T000000Z" indicates that the given sg never expires. |
|||
* The signature data as a hexadecimal-encoded string. The encoded data is the octet string given by section 8.1.1/8.2.1 of RSA PKCS #1, version 2.1. The data to be signed is described below. |
|||
* A space (if this sg confers a delegation) or a newline (terminating the signature chain). |
|||
The sig02 line validates a byte string called the 'certified |
|||
data'. For the final sg in the line, the 'data' field is a |
|||
signature of the string: |
|||
<serial number>:<expiration time>:<certified data> |
|||
using the keypair specified in the sg. For all other sgs, the 'data' |
|||
field is a signature of the string: |
|||
<serial number>:<expiration time>:<next public key in key01 format> |
|||
where key_1 is used to sign a string containing key_2, key_2 signs a |
|||
string containing key_3, etc. The key in the signed string must never |
|||
be abbreviated. Each delegation, and the final signature, is bound to |
|||
a specific laptop serial number (which should be the same if the |
|||
signature is to be meaningful). Use the sig01 format if you want an |
|||
unbound signature. |
|||
A sig02 with delegation is formed by concatenating the signature |
|||
of specific certified data onto a prefix of sgs which confer |
|||
authority. A sig02 without delegation still adds an expiration time and a serial-number binding to the equivalent sig01-format signature. |
|||
Validating a file containing sig01 and sig02 signatures starts by |
|||
scanning the file for sig01/sig02 signatures with an initial |
|||
'keyid' matching a trusted keypair. For a sig02, we then validate |
|||
each sg in turn until we reach the final sg, which should validate |
|||
against the certified data. |
|||
(sig02 [http://lists.laptop.org/pipermail/security/2008-June/000441.html discussion thread], [http://dev.laptop.org/~cscott/joyride-api/bitfrost.leases.crypto-module.html implementation]) |
|||
==Antitheft/Activation Lease== |
|||
act01: serial-number d expiration sig01: sha256 keyid data\n |
|||
3 2 2 11 111 16 1 3 2 2 6 1 64 1 N 1 |
|||
act01: serial-number d expiration sig02: sha256 keyid expiration data ...\n |
|||
3 2 2 11 111 16 1 3 2 2 6 1 64/N 1 16 1 M 1 |
|||
An activation lease begins with: |
|||
* The literal string 'act' |
|||
* The two digit version number ("01" for now) |
|||
* A colon |
|||
* A space |
|||
* The 11-character ASCII serial number of the machine this lease is for |
|||
* A space |
|||
* A one-character disposition |
|||
* A space |
|||
* The 16-character [http://en.wikipedia.org/wiki/ISO_8601 ISO 8601] UTC expiration time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z") |
|||
** should consist of the string "00000000T000000Z" if not present or not applicable. |
|||
It is then followed by a signature, in the sig01 or sig02 format above and with hashname "sha256", of the string: |
|||
<serial-number>:<uuid>:<disposition>:<expiration time> |
|||
where the expiration time in the string is identical in format and content to the signature expiration time. |
|||
For example: |
|||
SHF725001A0:414737D8-2312-9241-9C7B-9886CB74403C:K:20080819T052946Z |
|||
The disposition is ignored by firmware. Current userland behavior corresponds to disposition 'K'; we might support alternative dispositions in the future. |
|||
==Developer key== |
|||
dev01: serial-number d expiration sig01: sha256 keyid data\n |
|||
3 2 2 11 111 16 1 3 2 2 6 1 64 1 N 1 |
|||
dev01: serial-number d expiration sig02: sha256 keyid expiration data ...\n |
|||
3 2 2 11 111 16 1 3 2 2 6 1 64/N 1 16 1 M 1 |
|||
An developer key begins with: |
|||
* The literal string 'dev' |
|||
* The two digit version number ("01" for now) |
|||
* A colon |
|||
* A space |
|||
* The 11-character ASCII serial number of the machine this developer key is for |
|||
* A space |
|||
* The 1-character disposition |
|||
* A space |
|||
* The 16-character string '00000000T000000Z' |
|||
* A space |
|||
It is then followed by a signature, in the sig01 or sig02 format above and with hashname "sha256", of the string: |
|||
<serial-number>:<uuid>:<disposition>:00000000T000000Z |
|||
For example: |
|||
SHF725001A0:414737D8-2312-9241-9C7B-9886CB74403C:A:00000000T000000Z |
|||
Note that the payload is identical to that of an activation lease, although developer keys never expire. The verification key used also differs. |
|||
At the moment, developer keys always have disposition 'A'. |
|||
==RTC Set== |
|||
:::Draft under discussionas of March 2011 |
|||
rtc01: serial-number currentrtc nonce newrtc sig01: sha256 keyid data\n |
|||
3 2 2 11 1 16 1 10 16 3 2 2 6 1 64 1 N 1 |
|||
rtc01: serial-number currentrtc nonce newrtc sig02: sha256 keyid expiration data ...\n |
|||
3 2 2 11 1 16 1 10 16 3 2 2 6 1 64/N 1 16 1 M 1 |
|||
An activation lease begins with: |
|||
* The literal string 'rtc' |
|||
* The two digit version number ("01" for now) |
|||
* A colon |
|||
* A space |
|||
* The 11-character ASCII serial number of the machine this lease is for |
|||
* A space |
|||
* The 16-character [http://en.wikipedia.org/wiki/ISO_8601 ISO 8601] UTC current "last known good" RTC time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z") |
|||
* A space |
|||
* A zero-padded "nonce", based on the current "position" or "counter" of the RTC last-known-good-RTC value (needs better description from mitch). The counter is 32 bit. I've sized it to 10 chars to support representation in decimal -- we may use a different format. |
|||
* A space |
|||
* The 16-character [http://en.wikipedia.org/wiki/ISO_8601 ISO 8601] UTC current "last known good" RTC time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z") |
|||
It is then followed by a signature, in the sig01 or sig02 format above and with hashname "sha256", of the string: |
|||
<serial-number>:<uuid>:<currentrtc>:<nonce>:<newrtc> |
|||
==Resources== |
|||
* [ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf PKCS #1, v2.1] ([http://en.wikipedia.org/wiki/PKCS wikipedia]) |
|||
* [http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf ASN.1 DER] ([http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules wikipedia]) |
|||
[[Category:Firmware]] |
|||
[[Category:Security]] |
|||
[[Category:Specifications]] |
Latest revision as of 14:36, 23 March 2011
This page describes the key and signature formats understood by OFW. The Firmware Security page describes how these are used.
Key
key01: data\n 3 2 2 N 1
So that's:
- The literal string "key"
- The two digit version number ("01" for now)
- A colon
- A space
- The key data
- A newline
The key data is a hexadecimal-encoded octet string. The octet string is the ASN.1 DER encoding of an RSA public key given by Appendix A.1.1 of RSA PKCS #1, version 2.1.
Future versions of the key format might allow different algorithms.
Signature
Version 1
sig01: hashname keyid data\n 3 2 2 6 1 64 1 N 1
So that's:
- The literal string "sig"
- The two digit version number ("01" for now)
- A colon
- A space
- A six character name for the hash function used by this signature
- "sha256" indicates that this is an RSASSA-PSS signature using SHA256 as the hash and MGF1-SHA256 as the mask function.
- "rmd160" indicates that this is an RSASSA-PKCS1-v1_5 signature using RIPEMD-160 as the hash function.
- A space
- The 64 character key ID, which are the trailing 64 characters of the "key data" in the key format above. (for the immediate future you can ignore this in the firmware, and just use a single key for each task.)
- This includes the exponent and the least significant bytes of the modulus
- A space
- The signature data as a hexadecimal-encoded string. The encoded data is the octet string given by section 8.1.1/8.2.1 of RSA PKCS #1, version 2.1.
- A newline
Version 2
Version 2 signatures are (a) delegated, (b) tied to a particular serial number, and (c) may expire. The format is:
sig02: hashname_1 key-or-keyid_1 expiration_1 data_1 hashname_2 ...\n 3 2 2 6 1 N/64 1 16 1 M 1 ... 1
The "hashname key expiration data" section is repeated as many times as there are signatures in the chain. We will call each repetition an 'sg' below. So the contents of a sig02 are:
- The literal string "sig"
- The two digit version number ("02")
- A colon
- A space
At least one sg, consisting of:
- A six character name for the hash function used by this signature
- "sha256" indicates that this is an RSASSA-PSS signature using SHA256 as the hash and MGF1-SHA256 as the mask function.
- "rmd160" indicates that this is an RSASSA-PKCS1-v1_5 signature using RIPEMD-160 as the hash function.
- A space
- At least 64 characters of key data in the key01 format. The characters must be a suffix of the full key data; if more than 64 characters are present they are assumed to be the full key.
- 64 characters is sufficient to include the exponent and the least significant bytes of the modulus
- it is recommended that only keyid_1 be abbreviated.
- A space
- An ISO 8601 UTC expiration time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z"). After this time, the sg must no longer be considered valid.
- The string "00000000T000000Z" indicates that the given sg never expires.
- The signature data as a hexadecimal-encoded string. The encoded data is the octet string given by section 8.1.1/8.2.1 of RSA PKCS #1, version 2.1. The data to be signed is described below.
- A space (if this sg confers a delegation) or a newline (terminating the signature chain).
The sig02 line validates a byte string called the 'certified data'. For the final sg in the line, the 'data' field is a signature of the string:
<serial number>:<expiration time>:<certified data>
using the keypair specified in the sg. For all other sgs, the 'data' field is a signature of the string:
<serial number>:<expiration time>:<next public key in key01 format>
where key_1 is used to sign a string containing key_2, key_2 signs a string containing key_3, etc. The key in the signed string must never be abbreviated. Each delegation, and the final signature, is bound to a specific laptop serial number (which should be the same if the signature is to be meaningful). Use the sig01 format if you want an unbound signature.
A sig02 with delegation is formed by concatenating the signature of specific certified data onto a prefix of sgs which confer authority. A sig02 without delegation still adds an expiration time and a serial-number binding to the equivalent sig01-format signature.
Validating a file containing sig01 and sig02 signatures starts by scanning the file for sig01/sig02 signatures with an initial 'keyid' matching a trusted keypair. For a sig02, we then validate each sg in turn until we reach the final sg, which should validate against the certified data.
(sig02 discussion thread, implementation)
Antitheft/Activation Lease
act01: serial-number d expiration sig01: sha256 keyid data\n 3 2 2 11 111 16 1 3 2 2 6 1 64 1 N 1 act01: serial-number d expiration sig02: sha256 keyid expiration data ...\n 3 2 2 11 111 16 1 3 2 2 6 1 64/N 1 16 1 M 1
An activation lease begins with:
- The literal string 'act'
- The two digit version number ("01" for now)
- A colon
- A space
- The 11-character ASCII serial number of the machine this lease is for
- A space
- A one-character disposition
- A space
- The 16-character ISO 8601 UTC expiration time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z")
- should consist of the string "00000000T000000Z" if not present or not applicable.
It is then followed by a signature, in the sig01 or sig02 format above and with hashname "sha256", of the string:
<serial-number>:<uuid>:<disposition>:<expiration time>
where the expiration time in the string is identical in format and content to the signature expiration time.
For example:
SHF725001A0:414737D8-2312-9241-9C7B-9886CB74403C:K:20080819T052946Z
The disposition is ignored by firmware. Current userland behavior corresponds to disposition 'K'; we might support alternative dispositions in the future.
Developer key
dev01: serial-number d expiration sig01: sha256 keyid data\n 3 2 2 11 111 16 1 3 2 2 6 1 64 1 N 1 dev01: serial-number d expiration sig02: sha256 keyid expiration data ...\n 3 2 2 11 111 16 1 3 2 2 6 1 64/N 1 16 1 M 1
An developer key begins with:
- The literal string 'dev'
- The two digit version number ("01" for now)
- A colon
- A space
- The 11-character ASCII serial number of the machine this developer key is for
- A space
- The 1-character disposition
- A space
- The 16-character string '00000000T000000Z'
- A space
It is then followed by a signature, in the sig01 or sig02 format above and with hashname "sha256", of the string:
<serial-number>:<uuid>:<disposition>:00000000T000000Z
For example:
SHF725001A0:414737D8-2312-9241-9C7B-9886CB74403C:A:00000000T000000Z
Note that the payload is identical to that of an activation lease, although developer keys never expire. The verification key used also differs.
At the moment, developer keys always have disposition 'A'.
RTC Set
- Draft under discussionas of March 2011
rtc01: serial-number currentrtc nonce newrtc sig01: sha256 keyid data\n 3 2 2 11 1 16 1 10 16 3 2 2 6 1 64 1 N 1 rtc01: serial-number currentrtc nonce newrtc sig02: sha256 keyid expiration data ...\n 3 2 2 11 1 16 1 10 16 3 2 2 6 1 64/N 1 16 1 M 1
An activation lease begins with:
- The literal string 'rtc'
- The two digit version number ("01" for now)
- A colon
- A space
- The 11-character ASCII serial number of the machine this lease is for
- A space
- The 16-character ISO 8601 UTC current "last known good" RTC time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z")
- A space
- A zero-padded "nonce", based on the current "position" or "counter" of the RTC last-known-good-RTC value (needs better description from mitch). The counter is 32 bit. I've sized it to 10 chars to support representation in decimal -- we may use a different format.
- A space
- The 16-character ISO 8601 UTC current "last known good" RTC time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z")
It is then followed by a signature, in the sig01 or sig02 format above and with hashname "sha256", of the string:
<serial-number>:<uuid>:<currentrtc>:<nonce>:<newrtc>