QSA key token

The format of QSA public and private key tokens.

Table 2 and Table 3 show the format of QSA private and public key tokens. CCA allows the QSA algorithms and key sizes shown in Table 1 with the OID for each.
Table 1. Supported CRYSTALS-Dilithium and CRYSTALS-Kyber strengths
Size of matrix (n x n) NIST Round Size of t1 in bits OID in dot notation
CRYSTALS-Dilithium (6 x 5) Round 2 13824 1.3.6.1.4.1.2.267.1.6.5
CRYSTALS-Dilithium (8 x 7) Round 2 18432 1.3.6.1.4.1.2.267.1.8.7
CRYSTALS-Dilithium (6 x 5) Round 3 15360 1.3.6.1.4.1.2.267.7.6.5
CRYSTALS-Dilithium (8 x 7) Round 3 20480 1.3.6.1.4.1.2.267.7.8.7
CRYSTALS-Kyber (1024) Round 2 12288 1.3.6.1.4.1.2.267.5.4.4

A QSA key token is the concatenation of these ordered sections:

  1. A token header (required):
    • An external header (first byte X'1E'). CCA does not support key export.
    • An internal header (first byte X'1F'). Internal tokens are encrypted under the APKA MK-derived for QSA.
    PKA key-token Header (8 bytes)
    0 1 Token identifier (a flag that indicates token type):
    
    X'00' PKA null key-token.
    X'1E' PKA external key-token; the optional private-key is either 
          in cleartext or enciphered by a transport key-encrypting key.
    X'1F' PKA internal key-token; the private key is enciphered by a master key.
    
    1 1 Token version number (X'00').
    2 2 Length in bytes of the token structure (big endian).
    4 4 Reserved, binary zero.
  2. QSA private-key (optional) section in one of the token types.

    X’50’: QSA private key and OPK: SHA-256, AESKW encryption.

  3. QSA public-key (required) section.

    X'51': QSA public key section

  4. PKA private-key name (optional) section (section identifier X'10') .

    This section may be used on a CRYSTALS-Dilithium or CRYSTALS-Kyber key.

  5. PKA public-key certificate section (section identifier X'40' with subsidiary sections) .

    NOT USABLE with CRYSTALS-Dilithium or CRYSTALS-Kyber keys, there is no certificate format defined.

QSA token sizes

CRYSTALS-Kyber (1024 Round 2) QSA token:

  1. header: 8 B
  2. private section: 1776 B
  3. public section: 1592 B
  4. Total (no extra sections) : 3376 B

CRYSTALS-Dilithium (8,7 Round 2) QSA token:

  1. header: 8 B
  2. private section: 5280 B
  3. public section: 2360 B
  4. Total (no extra sections) : 7648 B

CRYSTALS-Dilithium (8,7 Round 3) QSA token:

  1. header: 8 B
  2. private section: 5008 B
  3. public section: 2616 B
  4. Total (no extra sections) : 7632 B

CRYSTALS-Dilithium (6,5 Round 2) QSA token:

  1. header: 8 B
  2. private section: 4000 B
  3. public section: 1784 B
  4. Total (no extra sections) : 5792 B

CRYSTALS-Dilithium (6,5 Round 3) QSA token:

  1. header: 8 B
  2. private section: 4144 B
  3. public section: 1976 B
  4. Total (no extra sections) : 6128 B
Table 2. QSA Private Key section with OPK (X’50’)
Offset (bytes) Length (bytes) Description
000 001 Section Identifier:
X'50'
QSA Private Key with AES-wrapped AES OPK
001 001 Section version number: X'00'.
002 002 Section length in bytes: 128 + ppp.

X'00' (Clear key)

Algorithm identifier (offset 9) Algorithm parameter (offset 10) ppp (in bytes) Section length (in bytes)
X'01' X'0605' 3824 3952
X'01' X'0807' 5104 5232
X'02' X'0768' 1216 1344
X'02' X'1024' 1600 1728
X'03' X'0605' 3968 4096
X'03' X'0807' 4832 4960
X'04' X'0768' 1216 1344
X'04' X'1024' 1600 1728

X'01' (Encrypted key)

Algorithm identifier (offset 9) Algorithm parameter (offset 10) ppp (in bytes) Section length (in bytes)
X'01' X'0605' 3872 4000
X'01' X'0807' 5152 5280
X'02' X'0768' 1264 1392
X'02' X'1024' 1648 1776
X'03' X'0605' 4016 4144
X'03' X'0807' 4880 5008
X'04' X'0768' 1264 1392
X'04' X'1024' 1648 1776
004 002 Length of associated data section in bytes: 54.
006 002 Reserved, binary zero.
008 001 Associated data section version number: X'01'.
009 001 Algorithm identifier:
X'00'
No algorithm.
X'01'
CRYSTALS-Dilithium - Round 2 :: PQA_ALGID_CRYS_DIL 0x01
X'02'
CRYSTALS-Kyber - Round 2 :: PQA_ALGID_CRYS_KYB 0x02
X'03'
CRYSTALS-Dilithium - Round 3 :: PQA_ALGID_CRYS_DIL_R3 0x03
X'04'
CRYSTALS-Kyber - Round 3 :: PQA_ALGID_CRYS_KYB_R3 0x04
010 002 Algorithm parameters:

When 'Algorithm identifier' is X'01', allowed values are:

X'0605'
CRYSTALS-Dilithium (6,5) :: PQA_ALGPARM_CRYS_DIL_65. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.1.6.5
X'0807'
CRYSTALS-Dilithium (8,7) :: PQA_ALGPARM_CRYS_DIL_87. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.1.8.7

When 'Algorithm identifier' is X'02', allowed values are:

X'0768'
CRYSTALS-Kyber (768) :: PQA_ALGPARM_CRYS_KYB_768. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.5.3.3
X'1024'
CRYSTALS-Kyber (1024) :: PQA_ALGPARM_CRYS_KYB_1024. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.5.4.4

When 'Algorithm identifier' is X'03', allowed values are:

X'0605'
CRYSTALS-Dilithium (6,5) :: PQA_ALGPARM_CRYS_DIL_65. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.7.6.5
X'0807'
CRYSTALS-Dilithium (8,7) :: PQA_ALGPARM_CRYS_DIL_87. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.7.8.7

When 'Algorithm identifier' is X'04', allowed values are:

X'0768'
CRYSTALS-Kyber (768) :: PQA_ALGPARM_CRYS_KYB_768. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.8.3.3
X'1024'
CRYSTALS-Kyber (1024) :: PQA_ALGPARM_CRYS_KYB_1024. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.8.4.4
012 001 Key format:
External token:
X'00'
Unencrypted QSA private key subsection identifier.
X'01'
Encrypted QSA private key subsection identifier.
Internal token:
X'01'
Encrypted QSA private key subsection identifier.

All other values are reserved and undefined.

013 001 Key source flag byte:
External token:
X'00'
No Key.
X'24'
Randomly generated.
Internal token:
X'00'
No Key.
X'21'
Imported from cleartext.
X'22'
Imported from ciphertext.
X'24'
Randomly generated.

All other values are reserved and undefined.

014 001 Compliance and export control byte:
Bit
Meaning
B'xxxx x1xx'
(Bit 5) Private key export allowed (AES1ECOK) .
B’xxxx x0xx’
(Bit 5) Private key export NOT allowed – default (NOAES1EC)
B'xxxx xx1x'
(Bit 6) Private key translation is allowed (XLATE-OK).
B'xxxx xx0x'
(Bit 6) Private key translation is NOT allowed (NO-XLATE).

All other values are reserved and undefined.

015 001 Hash type:
X'00'
Clear key.
X'02'
SHA-256.
016 002 Usage bytes, based on RFC 5280 (page 29: Bits in the KeyUsage type are used as follows):

Byte 48, bit number definitions, mapping to X.509, mapping to CCA CSNDPKB keywords, mapping to CCA services:

dl
(0 - 0x80), digitalSignature
== CSNDPKB:”U-DIGSIG” CSNDDSG (this private key), CSNDDSV (X.509/public key based on this private key). Usable for CRYSTALS-Dilithium keys.
(2 - 0x20), keyEncipherment
== CSNDPKB:”U-KEYENC”, CSNDSYI, CSNDSYI2, (this private key), CSNDSYX, CSNDSYG, (public key based on this private key). Usable for CRYSTALS-Kyber keys, may be combined with dataEncipherment.
(3 - 0x10), dataEncipherment
== CSNDPKB:”U-DATENC”, CSNDPKD (this private key), CSNDPKE (public key based on this private key). Usable for CRYSTALS-Kyber keys, may be combined with keyEncipherment.
0x4F, reserved
Not applicable with defined key algorithms.

Byte 2:

(8-15 – 0xFF), reserved
Must be 0x00.
018 032 SHA-256 hash value of:
  1. The public key section (section identifier X'51') and
  2. All optional sections that follow the public key section, if any.
If there are no optional sections, the hash covers only the public key section. If the key is clear, the field is binary zero bytes: X'00'.
050 002 'aaa' = QSA payload component 1 length.
Algorithm identifier (offset 9) Algorithm parameter (offset 10) aaa item description aaa value
X'01' X'0605' length of key D, also called 'seed' 32
X'01' X'0807' length of key D, also called 'seed' 32
X'02' X'0768' length of secret polynomial vector 1152
X'02' X'1024' length of secret polynomial vector 1536
X'03' X'0605' length of key D, also called 'seed' 32
X'03' X'0807' length of key D, also called 'seed' 32
X'04' X'0768' length of secret polynomial vector 1152
X'04' X'1024' length of secret polynomial vector 1536
052 002 'bbb' = QSA payload component 2 length.
Algorithm identifier (offset 9) Algorithm parameter (offset 10) bbb item description bbb value
X'01' X'0605' length of tr T : prf output 48
X'01' X'0807' length of tr T : prf output 48
X'02' X'0768' length of public key integrity check 32
X'02' X'1024' length of public key integrity check 32
X'03' X'0605' length of tr T : prf output 32
X'03' X'0807' length of tr T : prf output 32
X'04' X'0768' length of public key integrity check 32
X'04' X'1024' length of public key integrity check 32
054 002 'ccc' = QSA payload component 3 length.
Algorithm identifier (offset 9) Algorithm parameter (offset 10) ccc item description ccc value
X'01' X'0605' length of vector 's1', of L elements 480
X'01' X'0807' length of vector 's1', of L elements 672
X'02' X'0768' length of random data 32
X'02' X'1024' length of random data 32
X'03' X'0605' length of vector 's1', of L elements 640
X'03' X'0807' length of vector 's1', of L elements 672
X'04' X'0768' length of random data 32
X'04' X'1024' length of random data 32
056 002 'ddd' = QSA payload component 4 length.
Algorithm identifier (offset 9) Algorithm parameter (offset 10) ddd item description ddd value
X'01' X'0605' length of vector 's2', of K elements 576
X'01' X'0807' length of vector 's2', of K elements 768
X'02' X'0768' not used 0
X'02' X'1024' not used 0
X'03' X'0605' length of vector 's2', of K elements 768
X'03' X'0807' length of vector 's2', of K elements 768
X'04' X'0768' not used 0
X'04' X'1024' not used 0
058 002 'eee' = QSA payload component 5 length.
Algorithm identifier (offset 9) Algorithm parameter (offset 10) eee item description eee value
X'01' X'0605' length of 't0', K * high bits (vector) 2688
X'01' X'0807' length of 't0', K * high bits (vector) 3584
X'02' X'0768' not used 0
X'02' X'1024' not used 0
X'03' X'0605' length of 't0', K * high bits (vector) 2496
X'03' X'0807' length of 't0', K * high bits (vector) 3328
X'04' X'0768' not used 0
X'04' X'1024' not used 0
060 002 Reserved, binary zero.
062 056 Object Protection key (OPK) data: The OPK consists of a 16-byte confounder and a 256-bit AES key, followed by 8 bytes of AESKW overhead.
External token:
  • Encrypted: Encrypted by AES KEK.
  • Clear: All bytes binary zero.
Internal token
  • Encrypted: Encrypted with the APKA master key.
118 008 Key verification pattern (KVP):
When 'Key format' (offset 12) is:
X'00' (Clear key)
Binary zero.
X'01' (Encrypted key)
Bytes 0 – 7: KVP
  • When internal, this is the APKA master key verification pattern (MKVP).
  • When external, this is the KVP for the KEK.
126 002 Reserved, binary zero
128 ppp = (6 + 1 + 1 + 4 + 32 = 44) + (padlen>>3) + aaa + bbb + ccc + ddd + eee Formatted section (payload), including private key payload fields:
  1. X9.102 header fields: (x9102HashPtHdr_t)
    1. 6 B ICV
    2. 1 B padlen (in bits)
    3. 1 B hlen (H = 4 + 32)
    4. 4 B hashOpt
  2. 32 B: SHA256 hash over
    • Associated Data
  3. Sections of PQA private key
    • when 'Algorithm identifier' is X'01' (CRYSTALS-Dilithium)
      1. 'aaa' of component 1: key D
      2. 'bbb' of component 2: tr T
      3. 'ccc' of component 3: vector 's1'
      4. 'ddd' of component 4: vector 's2'
      5. 'eee' of component 5: 't0'
    • b. when 'Algorithm identifier' is X'02' (CRYSTALS-Kyber)
      1. 'aaa' of component 1: secret polynomial vector
      2. 'bbb' of component 2: public key integrity check
      3. 'ccc' of component 3: random data
      4. 'ddd' of component 4: unused
      5. 'eee' of component 5: unused
  4. padlen amount of padding of zero bits

Payload length:
For CRYSTALS-Dilithium (6,5) - Round 2:
ppp = 44 + (padlen>>3) + 32 + 48 + 480 + 576 + 2688
ppp = 3868 + (padlen>>3) ... padlen is '32': 32 0-bits for payload rounding.
ppp = 3872
For CRYSTALS-Dilithium (8,7) - Round 2:
ppp = 44 + (padlen>>3) + 32 + 48 + 672 + 768 + 3584
ppp = 5148 + (padlen>>3) ... padlen is '32' : 32 0-bits for payload rounding.
ppp = 5152
For CRYSTALS-Kyber (1024) - Round 2:
ppp = 44 + (padlen>>3) + 1536 + 32 + 32
ppp = 1644 + (padlen>>3) ... padlen is '32' : 32 0-bits for payload rounding.
ppp = 1648
For CRYSTALS-Dilithium (6,5) - Round 3:
ppp = 44 + (padlen>>3) + 32 + 32 + 640 + 768 + 2496
ppp = 4012 + (padlen>>3) ... padlen is '32' : 32 0-bits for payload rounding.
ppp = 4016
For CRYSTALS-Dilithium (8,7) - Round 3:
ppp = 44 + (padlen>>3) + 32 + 32 + 672 + 768 + 3328
ppp = 4876 + (padlen>>3) ... padlen is '32' : 32 0-bits for payload rounding.
ppp = 4880
Table 3. QSA Public Key section (X’51’)
Offset (bytes) Length (bytes) Description
000 001 Section Identifier:
X'51'
QSA Public Key.
001 001 Section version number: X'00'.
002 002 Section length: 24 + aaa + bbb

= 24 + 32 + 1728 = 1784 B for CRYSTALS-Dilithium - Round 2 (6,5)
= 24 + 32 + 2304 = 2360 B for CRYSTALS-Dilithium - Round 2 (8,7)
= 24 + 1536 + 32 = 1592 B for CRYSTALS-Kyber - Round 2 (1024)
= 24 + 32 + 1920 = 1976 B for CRYSTALS-Dilithium - Round 3 (6,5)
= 24 + 32 + 2560 = 2616 B for CRYSTALS-Dilithium - Round 3 (8,7)
004 001 Key format:
X'00'
No MAC over public key subsection.
005 001 Algorithm identifier:
X'00'
No algorithm.
X'01'
CRYSTALS-Dilithium - Round 2.
X'02'
CRYSTALS-Kyber - Round 2.
X'03'
CRYSTALS-Dilithium - Round 3.
X'04'
CRYSTALS-Kyber - Round 3.
006 002 Algorithm parameters:

When 'Algorithm identifier' is X'01', allowed values are:

X'0605'
CRYSTALS-Dilithium (6,5) :: PQA_ALGPARM_CRYS_DIL_65. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.1.6.5
X'0807'
CRYSTALS-Dilithium (8,7) :: PQA_ALGPARM_CRYS_DIL_87. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.1.8.7

When 'Algorithm identifier' is X'02', allowed values are:

X'0768'
CRYSTALS-Kyber (768) :: PQA_ALGPARM_CRYS_KYB_768. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.5.3.3
X'1024'
CRYSTALS-Kyber (1024) :: PQA_ALGPARM_CRYS_KYB_1024. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.5.4.4

When 'Algorithm identifier' is X'03', allowed values are:

X'0605'
CRYSTALS-Dilithium (6,5) :: PQA_ALGPARM_CRYS_DIL_65. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.7.6.5
X'0807'
CRYSTALS-Dilithium (8,7) :: PQA_ALGPARM_CRYS_DIL_87. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.7.8.7

When 'Algorithm identifier' is X'04', allowed values are:

X'0768'
CRYSTALS-Kyber (768) :: PQA_ALGPARM_CRYS_KYB_768. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.8.3.3
X'1024'
CRYSTALS-Kyber (1024) :: PQA_ALGPARM_CRYS_KYB_1024. OID for this algorithm and key parameter: 1.3.6.1.4.1.2.267.8.4.4
008 002 Usage bytes, based on RFC 5280 (page 29: Bits in the KeyUsage type are used as follows):

bit number definitions, mapping to X.509, mapping to CCA CSNDPKB keywords, mapping to CCA services:

Byte 8:,

(0 - 0x80), digitalSignature
== CSNDPKB:”U-DIGSIG” CSNDDSV (X.509/ this public key)
(2 - 0x20), keyEncipherment
== CSNDPKB:”U-KEYENC”, CSNDSYX, CSNDSYG, (this public key)
(3 - 0x10), dataEncipherment
== CSNDPKB:”U-DATENC”, CSNDPKE (this public key)
0x4F, reserved
- not applicable with the key algorithms so far defined

Byte 9:,

(8-15 – 0xFF), reserved
must be 0x00
010 002 'aaa' = QSA public component 1 length.
Algorithm identifier (offset 9) Algorithm parameter (offset 10) aaa item description aaa value
X'01' X'0605' length of 'rho', also called 'nonce' 32
X'01' X'0807' length of 'rho', also called 'nonce' 32
X'02' X'0768' length of public polynomial vector 1152
X'02' X'1024' length of public polynomial vector 1536
X'03' X'0605' length of 'rho', also called 'nonce' 32
X'03' X'0807' length of 'rho', also called 'nonce' 32
X'04' X'0768' length of public polynomial vector 1152
X'04' X'1024' length of public polynomial vector 1536
012 002 'bbb' = QSA public component 2 length.
Algorithm identifier (offset 9) Algorithm parameter (offset 10) bbb item description bbb value
X'01' X'0605' length of 't1' : K*low bits (vector) 1728
X'01' X'0807' length of 't1' : K*low bits (vector) 2304
X'02' X'0768' length of public seed 32
X'02' X'1024' length of public seed 32
X'03' X'0605' length of 't1' : K*low bits (vector) 1920
X'03' X'0807' length of 't1' : K*low bits (vector) 2560
X'04' X'0768' length of public seed 32
X'04' X'1024' length of public seed 32
014 010 Reserved, binary zero.
024 aaa PQA public component 1
Algorithm identifier (offset 9) Algorithm parameter (offset 10) aaa item description aaa length
X'01' X'0605' rho', also called 'nonce' 32
X'01' X'0807' rho', also called 'nonce' 32
X'02' X'1024' public polynomial vector 1536
X'03' X'0605' rho', also called 'nonce' 32
X'03' X'0807' rho', also called 'nonce' 32
024 + aaa bbb PQA public component 2
Algorithm identifier (offset 9) Algorithm parameter (offset 10) bbb item description bbb length
X'01' X'0605' 't1' : K*low bits (vector) 1728
X'01' X'0807' 't1' : K*low bits (vector) 2304
X'02' X'1024' public seed 32
X'03' X'0605' 't1' : K*low bits (vector) 1920
X'03' X'0807' 't1' : K*low bits (vector) 2560