Skip to content

Commit

Permalink
Add option to force usage of Padding Present Format for Key Component…
Browse files Browse the repository at this point in the history
… Block even though padding length is 0
  • Loading branch information
skythen committed Jul 5, 2021
1 parent 64c30d8 commit c9c40ac
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 85 deletions.
50 changes: 25 additions & 25 deletions key/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ type ComponentBasic struct {
// For some key components it is required to provide a key check value (e.g. for AES or DES keys).
//
// If you want to provide details regarding key usage and key access, use NewComponentExtended.
func NewComponentBasic(keyComponentType byte, keyComponentValue, kcv []byte, paddingLength int) *ComponentBasic {
func NewComponentBasic(keyComponentType byte, keyComponentValue, kcv []byte, paddingLength int, usePaddingPresentFormat bool) *ComponentBasic {
cb := &ComponentBasic{}

var block ComponentBlock

cb.Type = keyComponentType

if paddingLength != 0 {
if usePaddingPresentFormat || paddingLength != 0 {
block = ComponentPaddedBlock{
LengthComponent: len(keyComponentValue) - paddingLength,
Value: keyComponentValue,
Expand Down Expand Up @@ -159,8 +159,8 @@ type ComponentExtended struct {
// or a ComponentUnpaddedBlock (in case of no padding).
//
// For some key components it is required to provide a key check value (e.g. for AES or DES keys).
func NewComponentExtended(keyComponentType byte, keyComponentValue, kcv []byte, paddingLength int, keyUsage UsageQualifier, keyAccess util.NullByte) *ComponentExtended {
cb := NewComponentBasic(keyComponentType, keyComponentValue, kcv, paddingLength)
func NewComponentExtended(keyComponentType byte, keyComponentValue, kcv []byte, paddingLength int, keyUsage UsageQualifier, keyAccess util.NullByte, forcePaddedFormat bool) *ComponentExtended {
cb := NewComponentBasic(keyComponentType, keyComponentValue, kcv, paddingLength, forcePaddedFormat)

return &ComponentExtended{
ComponentBasic: *cb,
Expand Down Expand Up @@ -425,38 +425,38 @@ var (

// GetCurveParametersAk returns field parameters A and k of an elliptic curve as ComponentBasic.
// Supported curve names are: P-224, P-256, P-384, P-521, brainpoolP256t1, brainpoolP256r1, brainpoolP384t1, brainpoolP384r1, brainpoolP512t1 and brainpoolP512r1
func GetCurveParametersAk(curvename string) (kcParameterA, kcParameterK *ComponentBasic, err error) {
func GetCurveParametersAk(curvename string, usePaddingPresentFormat bool) (kcParameterA, kcParameterK *ComponentBasic, err error) {
switch curvename {
case "P-224":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp224r1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp224r1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0, usePaddingPresentFormat)
case "P-256":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp256r1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp256r1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0, usePaddingPresentFormat)
case "P-384":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp384r1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp384r1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0, usePaddingPresentFormat)
case "P-521":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp521r1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, secp521r1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, secpr1k, nil, 0, usePaddingPresentFormat)
case "brainpoolP256t1":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP256t1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP256t1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0, usePaddingPresentFormat)
case "brainpoolP256r1":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP256r1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP256r1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0, usePaddingPresentFormat)
case "brainpoolP384t1":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP384t1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP384t1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0, usePaddingPresentFormat)
case "brainpoolP384r1":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP384r1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP384r1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0, usePaddingPresentFormat)
case "brainpoolP512t1":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP512t1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP512t1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0, usePaddingPresentFormat)
case "brainpoolP512r1":
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP512r1A, nil, 0)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0)
kcParameterA = NewComponentBasic(TypeECCFieldParameterA, brainpoolP512r1A, nil, 0, usePaddingPresentFormat)
kcParameterK = NewComponentBasic(TypeECCFieldParameterK, brainpool1K, nil, 0, usePaddingPresentFormat)
default:
return nil, nil, errors.New("unsupported curve or unknown curve name")
}
Expand Down
153 changes: 93 additions & 60 deletions key/key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,22 @@ import (

func TestNewKeyComponentBasicEncrypted(t *testing.T) {
tests := []struct {
name string
inputKeyType byte
inputEncryptedKey []byte
inputKCV []byte
inputPaddingLength int
expected *ComponentBasic
expectError bool
name string
inputKeyType byte
inputEncryptedKey []byte
inputKCV []byte
inputPaddingLength int
inputUsePaddingPresentFormat bool
expected *ComponentBasic
expectError bool
}{
{
name: "Unpadded Block, DES key",
inputKeyType: 0x80,
inputEncryptedKey: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4},
inputKCV: []byte{0x51, 0xBB, 0xED},
inputPaddingLength: 0,
name: "Unpadded Block, DES key",
inputKeyType: 0x80,
inputEncryptedKey: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4},
inputKCV: []byte{0x51, 0xBB, 0xED},
inputPaddingLength: 0,
inputUsePaddingPresentFormat: false,
expected: &ComponentBasic{
Type: 0x80,
Block: ComponentUnpaddedBlock{Value: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4}},
Expand All @@ -31,11 +33,28 @@ func TestNewKeyComponentBasicEncrypted(t *testing.T) {
expectError: false,
},
{
name: "Unpadded Block, AES key",
inputKeyType: 0x88,
inputEncryptedKey: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4},
inputKCV: []byte{0x17, 0x96, 0x72},
inputPaddingLength: 0,
name: "Unpadded Block, DES key, use padding present format",
inputKeyType: 0x80,
inputEncryptedKey: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4},
inputKCV: []byte{0x51, 0xBB, 0xED},
inputPaddingLength: 0,
inputUsePaddingPresentFormat: true,
expected: &ComponentBasic{
Type: 0x80,
Block: ComponentPaddedBlock{
LengthComponent: 16,
Value: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4}},
KCV: []byte{0x51, 0xBB, 0xED},
},
expectError: false,
},
{
name: "Unpadded Block, AES key",
inputKeyType: 0x88,
inputEncryptedKey: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4},
inputKCV: []byte{0x17, 0x96, 0x72},
inputPaddingLength: 0,
inputUsePaddingPresentFormat: false,
expected: &ComponentBasic{
Type: 0x88,
Block: ComponentUnpaddedBlock{Value: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4}},
Expand All @@ -44,11 +63,12 @@ func TestNewKeyComponentBasicEncrypted(t *testing.T) {
expectError: false,
},
{
name: "Padded Block",
inputKeyType: 0x55,
inputEncryptedKey: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5},
inputKCV: nil,
inputPaddingLength: 1,
name: "Padded Block",
inputKeyType: 0x55,
inputEncryptedKey: []byte{0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5},
inputKCV: nil,
inputPaddingLength: 1,
inputUsePaddingPresentFormat: false,
expected: &ComponentBasic{
Type: 0x55,
Block: ComponentPaddedBlock{
Expand All @@ -62,7 +82,7 @@ func TestNewKeyComponentBasicEncrypted(t *testing.T) {

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
received := NewComponentBasic(tc.inputKeyType, tc.inputEncryptedKey, tc.inputKCV, tc.inputPaddingLength)
received := NewComponentBasic(tc.inputKeyType, tc.inputEncryptedKey, tc.inputKCV, tc.inputPaddingLength, tc.inputUsePaddingPresentFormat)

if !cmp.Equal(tc.expected, received) {
t.Errorf("Expected: '%v', got: '%v'", tc.expected, received)
Expand All @@ -73,15 +93,16 @@ func TestNewKeyComponentBasicEncrypted(t *testing.T) {

func TestNewKeyComponentExtendedEncrypted(t *testing.T) {
tests := []struct {
name string
inputKeyType byte
inputKey []byte
inputKCV []byte
inputKeyUsage UsageQualifier
inputKeyAccess util.NullByte
inputPaddingLength int
expected *ComponentExtended
expectError bool
name string
inputKeyType byte
inputKey []byte
inputKCV []byte
inputKeyUsage UsageQualifier
inputKeyAccess util.NullByte
inputPaddingLength int
inputUsePaddingPresentFormat bool
expected *ComponentExtended
expectError bool
}{
{
name: "no error, padded block ",
Expand All @@ -93,7 +114,8 @@ func TestNewKeyComponentExtendedEncrypted(t *testing.T) {
Byte: AccessSdOnly,
Valid: true,
},
inputPaddingLength: 1,
inputPaddingLength: 1,
inputUsePaddingPresentFormat: false,
expected: &ComponentExtended{
ComponentBasic: ComponentBasic{
Type: 0x50,
Expand All @@ -114,7 +136,7 @@ func TestNewKeyComponentExtendedEncrypted(t *testing.T) {

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
received := NewComponentExtended(tc.inputKeyType, tc.inputKey, tc.inputKCV, tc.inputPaddingLength, tc.inputKeyUsage, tc.inputKeyAccess)
received := NewComponentExtended(tc.inputKeyType, tc.inputKey, tc.inputKCV, tc.inputPaddingLength, tc.inputKeyUsage, tc.inputKeyAccess, tc.inputUsePaddingPresentFormat)

if !cmp.Equal(tc.expected, received) {
t.Errorf("Expected: '%v', got: '%v'", tc.expected, received)
Expand Down Expand Up @@ -526,15 +548,17 @@ func TestKeyDataExtended_Bytes(t *testing.T) {

func TestGetCurveParametersAk(t *testing.T) {
tests := []struct {
name string
inputCurveName string
expectedA *ComponentBasic
expectedK *ComponentBasic
expectError bool
name string
inputCurveName string
inputUsePaddingPresentFormat bool
expectedA *ComponentBasic
expectedK *ComponentBasic
expectError bool
}{
{
name: "P-224",
inputCurveName: "P-224",
name: "P-224",
inputCurveName: "P-224",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{secp224r1A},
Expand All @@ -546,8 +570,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "P-256",
inputCurveName: "P-256",
name: "P-256",
inputCurveName: "P-256",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{secp256r1A},
Expand All @@ -559,8 +584,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "P-384",
inputCurveName: "P-384",
name: "P-384",
inputCurveName: "P-384",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{secp384r1A},
Expand All @@ -572,8 +598,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "P-521",
inputCurveName: "P-521",
name: "P-521",
inputCurveName: "P-521",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{secp521r1A},
Expand All @@ -585,8 +612,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "brainpoolP256t1",
inputCurveName: "brainpoolP256t1",
name: "brainpoolP256t1",
inputCurveName: "brainpoolP256t1",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{brainpoolP256t1A},
Expand All @@ -598,8 +626,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "brainpoolP256r1",
inputCurveName: "brainpoolP256r1",
name: "brainpoolP256r1",
inputCurveName: "brainpoolP256r1",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{brainpoolP256r1A},
Expand All @@ -611,8 +640,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "brainpoolP384t1",
inputCurveName: "brainpoolP384t1",
name: "brainpoolP384t1",
inputCurveName: "brainpoolP384t1",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{brainpoolP384t1A},
Expand All @@ -624,8 +654,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "brainpoolP384r1",
inputCurveName: "brainpoolP384r1",
name: "brainpoolP384r1",
inputCurveName: "brainpoolP384r1",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{brainpoolP384r1A},
Expand All @@ -637,8 +668,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "brainpoolP512r1",
inputCurveName: "brainpoolP512r1",
name: "brainpoolP512r1",
inputCurveName: "brainpoolP512r1",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{brainpoolP512r1A},
Expand All @@ -650,8 +682,9 @@ func TestGetCurveParametersAk(t *testing.T) {
expectError: false,
},
{
name: "brainpoolP512t1",
inputCurveName: "brainpoolP512t1",
name: "brainpoolP512t1",
inputCurveName: "brainpoolP512t1",
inputUsePaddingPresentFormat: false,
expectedA: &ComponentBasic{
Type: 0xB3,
Block: ComponentUnpaddedBlock{brainpoolP512t1A},
Expand All @@ -673,7 +706,7 @@ func TestGetCurveParametersAk(t *testing.T) {

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
receivedA, receivedK, err := GetCurveParametersAk(tc.inputCurveName)
receivedA, receivedK, err := GetCurveParametersAk(tc.inputCurveName, tc.inputUsePaddingPresentFormat)

if err != nil && !tc.expectError {
t.Errorf("Expected: no error, got: error(%v)", err.Error())
Expand Down

0 comments on commit c9c40ac

Please sign in to comment.