From 083f89768f4355283019e9758c2ee293c6569a95 Mon Sep 17 00:00:00 2001 From: allen0091 <44120584+allen0091@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:53:25 +0800 Subject: [PATCH] Encrypt nil Ike payload (#12) * Encrypt nil Ike payload * Add nil ike payload encryption in UT * Add random padding in encrypt procedure * Add encr aes_cbc UT * Modify Algo name to global parameter * Modify Encr NewCrypto parameter * Modify algo struct name * Fix UT fail due to naming issue --------- Co-authored-by: Allen00991 --- ike.go | 14 +- ike_test.go | 379 +++++++++++++---------- security/dh/dh.go | 13 +- security/dh/dh_1024_bit_modp.go | 15 +- security/dh/dh_2048_bit_modp.go | 15 +- security/encr/encr.go | 12 +- security/encr/encr_aes_cbc.go | 93 +++--- security/encr/encr_aes_cbc128_test.go | 173 +++++++++++ security/encr/encr_aes_cbc192_test.go | 172 ++++++++++ security/encr/encr_aes_cbc256_test.go | 173 +++++++++++ security/esn/esn.go | 12 +- security/integ/auth_hmac_md5_96.go | 20 +- security/integ/auth_hmac_sha1_96.go | 20 +- security/integ/auth_hmac_sha2_256_128.go | 20 +- security/integ/integ.go | 18 +- security/lib/lib.go | 22 +- security/prf/prf.go | 12 +- security/prf/prf_hmac_md5.go | 18 +- security/prf/prf_hmac_sha1.go | 18 +- security/prf/prf_hmac_sha2_256.go | 18 +- 20 files changed, 927 insertions(+), 310 deletions(-) create mode 100644 security/encr/encr_aes_cbc128_test.go create mode 100644 security/encr/encr_aes_cbc192_test.go create mode 100644 security/encr/encr_aes_cbc256_test.go diff --git a/ike.go b/ike.go index af776f6..8a621a3 100644 --- a/ike.go +++ b/ike.go @@ -237,10 +237,7 @@ func encryptMsg( return errors.Errorf("encryptMsg(): IKE SA is nil") } ikePayloads := ikeMsg.Payloads - // Check parameters - if len(ikePayloads) == 0 { - return errors.Errorf("encryptMsg(): No IKE payload to be encrypted") - } + // Check if the context contain needed data if ikesaKey.IntegInfo == nil { return errors.Errorf("encryptMsg(): No integrity algorithm specified") @@ -271,7 +268,14 @@ func encryptMsg( encryptedData = append(encryptedData, make([]byte, checksumLength)...) ikeMsg.Payloads.Reset() - sk := ikeMsg.Payloads.BuildEncrypted(ikePayloads[0].Type(), encryptedData) + + var encrNextPayloadType message.IKEPayloadType + if len(ikePayloads) == 0 { + encrNextPayloadType = message.NoNext + } else { + encrNextPayloadType = ikePayloads[0].Type() + } + sk := ikeMsg.Payloads.BuildEncrypted(encrNextPayloadType, encryptedData) // Calculate checksum ikeMsgData, err := ikeMsg.Encode() diff --git a/ike_test.go b/ike_test.go index 8bbbb58..dbd4612 100644 --- a/ike_test.go +++ b/ike_test.go @@ -1,6 +1,8 @@ package ike import ( + "crypto/aes" + "crypto/cipher" "encoding/hex" "testing" @@ -12,6 +14,67 @@ import ( "github.com/free5gc/ike/security/integ" ) +var ( + eapIkeMsg = message.IKEMessage{ + IKEHeader: &message.IKEHeader{ + InitiatorSPI: 0x000000000006f708, + ResponderSPI: 0xc9e2e31f8b64053d, + MajorVersion: 2, + MinorVersion: 0, + ExchangeType: message.IKE_AUTH, + Flags: message.InitiatorBitCheck, + MessageID: 0x03, + NextPayload: uint8(message.TypeSK), + PayloadBytes: []byte{ + 0x30, 0x00, 0x00, 0x50, 0xec, 0x50, 0x31, 0x16, + 0x2c, 0x69, 0x2f, 0xbb, 0xfc, 0x4d, 0x20, 0x64, + 0x0c, 0x91, 0x21, 0xeb, 0xe9, 0x47, 0x5e, 0xf9, + 0x4f, 0x9b, 0x02, 0x95, 0x9d, 0x31, 0x24, 0x2e, + 0x53, 0x5e, 0x9c, 0x3c, 0x4d, 0xca, 0xec, 0xd1, + 0xbf, 0xd6, 0xdd, 0x80, 0xaa, 0x81, 0x2b, 0x07, + 0xde, 0x36, 0xde, 0xe9, 0xb7, 0x50, 0x94, 0x35, + 0xf6, 0x35, 0xe1, 0xaa, 0xae, 0x1c, 0x38, 0x25, + 0xf4, 0xea, 0xe3, 0x38, 0x49, 0x03, 0xf7, 0x24, + 0xf4, 0x44, 0x17, 0x0c, 0x68, 0x45, 0xca, 0x80, + }, + }, + Payloads: message.IKEPayloadContainer{ + &message.EAP{ + Code: 0x02, + Identifier: 0x3b, + EAPTypeData: []message.EAPTypeFormat{ + &message.EAPExpanded{ + VendorID: 0x28af, + VendorType: 0x03, + VendorData: []byte{ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x15, 0x7e, 0x00, + 0x57, 0x2d, 0x10, 0xf5, 0x07, 0x36, 0x2e, 0x32, + 0x2d, 0xe3, 0x68, 0x57, 0x93, 0x65, 0xd2, 0x86, + 0x2b, 0x50, 0xed, + }, + }, + }, + }, + }, + } + eapRawMsg = []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf7, 0x08, + 0xc9, 0xe2, 0xe3, 0x1f, 0x8b, 0x64, 0x05, 0x3d, + 0x2e, 0x20, 0x23, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x6c, 0x30, 0x00, 0x00, 0x50, + 0xec, 0x50, 0x31, 0x16, 0x2c, 0x69, 0x2f, 0xbb, + 0xfc, 0x4d, 0x20, 0x64, 0x0c, 0x91, 0x21, 0xeb, + 0xe9, 0x47, 0x5e, 0xf9, 0x4f, 0x9b, 0x02, 0x95, + 0x9d, 0x31, 0x24, 0x2e, 0x53, 0x5e, 0x9c, 0x3c, + 0x4d, 0xca, 0xec, 0xd1, 0xbf, 0xd6, 0xdd, 0x80, + 0xaa, 0x81, 0x2b, 0x07, 0xde, 0x36, 0xde, 0xe9, + 0xb7, 0x50, 0x94, 0x35, 0xf6, 0x35, 0xe1, 0xaa, + 0xae, 0x1c, 0x38, 0x25, 0xf4, 0xea, 0xe3, 0x38, + 0x49, 0x03, 0xf7, 0x24, 0xf4, 0x44, 0x17, 0x0c, + 0x68, 0x45, 0xca, 0x80, + } +) + func TestEncodeDecode(t *testing.T) { encryptionAlgorithm := encr.StrToType("ENCR_AES_CBC_256") @@ -112,22 +175,7 @@ func TestDecodeDecrypt(t *testing.T) { }{ { description: "decrypt with key", - b: []byte{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf7, 0x08, - 0xc9, 0xe2, 0xe3, 0x1f, 0x8b, 0x64, 0x05, 0x3d, - 0x2e, 0x20, 0x23, 0x08, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x6c, 0x30, 0x00, 0x00, 0x50, - 0xec, 0x50, 0x31, 0x16, 0x2c, 0x69, 0x2f, 0xbb, - 0xfc, 0x4d, 0x20, 0x64, 0x0c, 0x91, 0x21, 0xeb, - 0xe9, 0x47, 0x5e, 0xf9, 0x4f, 0x9b, 0x02, 0x95, - 0x9d, 0x31, 0x24, 0x2e, 0x53, 0x5e, 0x9c, 0x3c, - 0x4d, 0xca, 0xec, 0xd1, 0xbf, 0xd6, 0xdd, 0x80, - 0xaa, 0x81, 0x2b, 0x07, 0xde, 0x36, 0xde, 0xe9, - 0xb7, 0x50, 0x94, 0x35, 0xf6, 0x35, 0xe1, 0xaa, - 0xae, 0x1c, 0x38, 0x25, 0xf4, 0xea, 0xe3, 0x38, - 0x49, 0x03, 0xf7, 0x24, 0xf4, 0x44, 0x17, 0x0c, - 0x68, 0x45, 0xca, 0x80, - }, + b: eapRawMsg, ikeSAKey: &security.IKESAKey{ EncrInfo: encr.StrToType("ENCR_AES_CBC_256"), IntegInfo: integ.StrToType("AUTH_HMAC_SHA1_96"), @@ -154,69 +202,13 @@ func TestDecodeDecrypt(t *testing.T) { 0x8c, 0x7d, 0xb6, 0x0b, 0xed, 0x07, 0xe2, 0x45, 0x38, 0xb1, 0x9b, 0xb0, }, - expErr: false, - expIkeMsg: &message.IKEMessage{ - IKEHeader: &message.IKEHeader{ - InitiatorSPI: 0x000000000006f708, - ResponderSPI: 0xc9e2e31f8b64053d, - MajorVersion: 2, - MinorVersion: 0, - ExchangeType: message.IKE_AUTH, - Flags: message.InitiatorBitCheck, - MessageID: 0x03, - NextPayload: uint8(message.TypeSK), - PayloadBytes: []byte{ - 0x30, 0x00, 0x00, 0x50, 0xec, 0x50, 0x31, 0x16, - 0x2c, 0x69, 0x2f, 0xbb, 0xfc, 0x4d, 0x20, 0x64, - 0x0c, 0x91, 0x21, 0xeb, 0xe9, 0x47, 0x5e, 0xf9, - 0x4f, 0x9b, 0x02, 0x95, 0x9d, 0x31, 0x24, 0x2e, - 0x53, 0x5e, 0x9c, 0x3c, 0x4d, 0xca, 0xec, 0xd1, - 0xbf, 0xd6, 0xdd, 0x80, 0xaa, 0x81, 0x2b, 0x07, - 0xde, 0x36, 0xde, 0xe9, 0xb7, 0x50, 0x94, 0x35, - 0xf6, 0x35, 0xe1, 0xaa, 0xae, 0x1c, 0x38, 0x25, - 0xf4, 0xea, 0xe3, 0x38, 0x49, 0x03, 0xf7, 0x24, - 0xf4, 0x44, 0x17, 0x0c, 0x68, 0x45, 0xca, 0x80, - }, - }, - Payloads: message.IKEPayloadContainer{ - &message.EAP{ - Code: 0x02, - Identifier: 0x3b, - EAPTypeData: []message.EAPTypeFormat{ - &message.EAPExpanded{ - VendorID: 0x28af, - VendorType: 0x03, - VendorData: []byte{ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x15, 0x7e, 0x00, - 0x57, 0x2d, 0x10, 0xf5, 0x07, 0x36, 0x2e, 0x32, - 0x2d, 0xe3, 0x68, 0x57, 0x93, 0x65, 0xd2, 0x86, - 0x2b, 0x50, 0xed, - }, - }, - }, - }, - }, - }, + expErr: false, + expIkeMsg: &eapIkeMsg, }, { description: "decrypt without key", - b: []byte{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf7, 0x08, - 0xc9, 0xe2, 0xe3, 0x1f, 0x8b, 0x64, 0x05, 0x3d, - 0x2e, 0x20, 0x23, 0x08, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x6c, 0x30, 0x00, 0x00, 0x50, - 0xec, 0x50, 0x31, 0x16, 0x2c, 0x69, 0x2f, 0xbb, - 0xfc, 0x4d, 0x20, 0x64, 0x0c, 0x91, 0x21, 0xeb, - 0xe9, 0x47, 0x5e, 0xf9, 0x4f, 0x9b, 0x02, 0x95, - 0x9d, 0x31, 0x24, 0x2e, 0x53, 0x5e, 0x9c, 0x3c, - 0x4d, 0xca, 0xec, 0xd1, 0xbf, 0xd6, 0xdd, 0x80, - 0xaa, 0x81, 0x2b, 0x07, 0xde, 0x36, 0xde, 0xe9, - 0xb7, 0x50, 0x94, 0x35, 0xf6, 0x35, 0xe1, 0xaa, - 0xae, 0x1c, 0x38, 0x25, 0xf4, 0xea, 0xe3, 0x38, - 0x49, 0x03, 0xf7, 0x24, 0xf4, 0x44, 0x17, 0x0c, - 0x68, 0x45, 0xca, 0x80, - }, - expErr: true, + b: eapRawMsg, + expErr: true, }, { description: "msg len less than IKE_HEADER_LEN", @@ -225,22 +217,7 @@ func TestDecodeDecrypt(t *testing.T) { }, { description: "no sk_ai", - b: []byte{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf7, 0x08, - 0xc9, 0xe2, 0xe3, 0x1f, 0x8b, 0x64, 0x05, 0x3d, - 0x2e, 0x20, 0x23, 0x08, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x6c, 0x30, 0x00, 0x00, 0x50, - 0xec, 0x50, 0x31, 0x16, 0x2c, 0x69, 0x2f, 0xbb, - 0xfc, 0x4d, 0x20, 0x64, 0x0c, 0x91, 0x21, 0xeb, - 0xe9, 0x47, 0x5e, 0xf9, 0x4f, 0x9b, 0x02, 0x95, - 0x9d, 0x31, 0x24, 0x2e, 0x53, 0x5e, 0x9c, 0x3c, - 0x4d, 0xca, 0xec, 0xd1, 0xbf, 0xd6, 0xdd, 0x80, - 0xaa, 0x81, 0x2b, 0x07, 0xde, 0x36, 0xde, 0xe9, - 0xb7, 0x50, 0x94, 0x35, 0xf6, 0x35, 0xe1, 0xaa, - 0xae, 0x1c, 0x38, 0x25, 0xf4, 0xea, 0xe3, 0x38, - 0x49, 0x03, 0xf7, 0x24, 0xf4, 0x44, 0x17, 0x0c, - 0x68, 0x45, 0xca, 0x80, - }, + b: eapRawMsg, ikeSAKey: &security.IKESAKey{ EncrInfo: encr.StrToType("ENCR_AES_CBC_256"), IntegInfo: integ.StrToType("AUTH_HMAC_SHA1_96"), @@ -266,22 +243,7 @@ func TestDecodeDecrypt(t *testing.T) { }, { description: "no sk_ei", - b: []byte{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf7, 0x08, - 0xc9, 0xe2, 0xe3, 0x1f, 0x8b, 0x64, 0x05, 0x3d, - 0x2e, 0x20, 0x23, 0x08, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x6c, 0x30, 0x00, 0x00, 0x50, - 0xec, 0x50, 0x31, 0x16, 0x2c, 0x69, 0x2f, 0xbb, - 0xfc, 0x4d, 0x20, 0x64, 0x0c, 0x91, 0x21, 0xeb, - 0xe9, 0x47, 0x5e, 0xf9, 0x4f, 0x9b, 0x02, 0x95, - 0x9d, 0x31, 0x24, 0x2e, 0x53, 0x5e, 0x9c, 0x3c, - 0x4d, 0xca, 0xec, 0xd1, 0xbf, 0xd6, 0xdd, 0x80, - 0xaa, 0x81, 0x2b, 0x07, 0xde, 0x36, 0xde, 0xe9, - 0xb7, 0x50, 0x94, 0x35, 0xf6, 0x35, 0xe1, 0xaa, - 0xae, 0x1c, 0x38, 0x25, 0xf4, 0xea, 0xe3, 0x38, - 0x49, 0x03, 0xf7, 0x24, 0xf4, 0x44, 0x17, 0x0c, - 0x68, 0x45, 0xca, 0x80, - }, + b: eapRawMsg, ikeSAKey: &security.IKESAKey{ EncrInfo: encr.StrToType("ENCR_AES_CBC_256"), IntegInfo: integ.StrToType("AUTH_HMAC_SHA1_96"), @@ -388,7 +350,6 @@ func TestDecodeDecrypt(t *testing.T) { func TestEncryptMsg(t *testing.T) { encryptionAlgorithm := encr.StrToType("ENCR_AES_CBC_256") - integrityAlgorithm := integ.StrToType("AUTH_HMAC_SHA1_96") ikeSAKey := &security.IKESAKey{ @@ -397,112 +358,208 @@ func TestEncryptMsg(t *testing.T) { } var err error - sk_ei, err := hex.DecodeString( - "3d7a26417122cee9c77c59f375b024cdb9f0b5777ea18b50f8a671fd3b2daa99") + var iv, padding, sk_ei, sk_er, sk_ai, sk_ar []byte + var ikeMsg *message.IKEMessage + var block cipher.Block + + iv = []byte{ + 0xa2, 0xfb, 0xbc, 0xdd, 0xd3, 0x9a, 0xda, 0xdd, + 0x67, 0x10, 0xbc, 0x38, 0x33, 0xc0, 0x23, 0x72, + } + padding = []byte{ + 0xe6, 0x59, 0x7d, 0x13, 0x9a, 0xa0, 0xd9, 0x3b, + 0x08, + } + sk_ei, err = hex.DecodeString( + "b2e0279136e0477624e635e53e561c0b241d1388f3ea0873496e835b48c17508") require.NoError(t, err) - ikeSAKey.Encr_i, err = ikeSAKey.EncrInfo.NewCrypto(sk_ei) + + block, err = aes.NewCipher(sk_ei) require.NoError(t, err) + ikeSAKey.Encr_i = &encr.EncrAesCbcCrypto{ + Block: block, + Iv: iv, + Padding: padding, + } - sk_er, err := hex.DecodeString( - "3ea57e7ddfb30756a04619a9873333b08e94deef05b6a05d7eb3dba075d81c6f") + sk_er, err = hex.DecodeString( + "71919fd9d651da48fe141d0e6735d9a2ffc4512354db293c7b4c35f0fab62242") require.NoError(t, err) - ikeSAKey.Encr_r, err = ikeSAKey.EncrInfo.NewCrypto(sk_er) + + block, err = aes.NewCipher(sk_er) require.NoError(t, err) + ikeSAKey.Encr_r = &encr.EncrAesCbcCrypto{ + Block: block, + Iv: iv, + Padding: padding, + } - sk_ai, err := hex.DecodeString( - "ab8047415535cf53e19a69e2c86feadfebfff1e9") + sk_ai, err = hex.DecodeString( + "f63878f3236929f870fe5e4f58621084b8be0c86") require.NoError(t, err) ikeSAKey.Integ_i = ikeSAKey.IntegInfo.Init(sk_ai) - sk_ar, err := hex.DecodeString( - "16d5ae6f2859a73a8c7db60bed07e24538b19bb0") + sk_ar, err = hex.DecodeString( + "63204bde31bfd4e142081bb7beaba3819bf09aad") require.NoError(t, err) integ_r := ikeSAKey.IntegInfo.Init(sk_ar) ikeSAKey.Integ_r = integ_r - ikeMessage := &message.IKEMessage{ + ikeMsg = &message.IKEMessage{ IKEHeader: &message.IKEHeader{ - ResponderSPI: 0xc9e2e31f8b64053d, - InitiatorSPI: 0x000000000006f708, + InitiatorSPI: 0x494e377c00000000, + ResponderSPI: 0x8ea9e2fc844bfaaf, MajorVersion: 2, MinorVersion: 0, ExchangeType: message.IKE_AUTH, - Flags: message.InitiatorBitCheck, + Flags: 0x20, MessageID: 0x03, + NextPayload: uint8(message.TypeEAP), }, - } - - ikePayloads := message.IKEPayloadContainer{ - &message.EAP{ - Code: 0x02, - Identifier: 0x3b, - EAPTypeData: message.EAPTypeDataContainer{ - &message.EAPExpanded{ - VendorID: 0x28af, - VendorType: 0x03, - VendorData: []byte{ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x15, 0x7e, 0x00, - 0x57, 0x2d, 0x10, 0xf5, 0x07, 0x36, 0x2e, 0x32, - 0x2d, 0xe3, 0x68, 0x57, 0x93, 0x65, 0xd2, 0x86, - 0x2b, 0x50, 0xed, + Payloads: message.IKEPayloadContainer{ + &message.EAP{ + Code: 0x01, + Identifier: 0xd9, + EAPTypeData: []message.EAPTypeFormat{ + &message.EAPExpanded{ + VendorID: 0x28af, + VendorType: 0x03, + VendorData: []byte{ + 0x02, 0x00, 0x00, 0x13, 0x7e, 0x03, 0x22, 0xe7, + 0x63, 0xcb, 0x00, 0x7e, 0x00, 0x5d, 0x02, 0x00, + 0x02, 0x80, 0x20, 0xe1, 0x36, 0x01, 0x02, + }, }, }, }, }, } - ikeMessage.Payloads = ikePayloads - - // Successful encryption - err = encryptMsg(ikeMessage, ikeSAKey, message.Role_Initiator) - require.NoError(t, err) - - rawMsg, err := ikeMessage.Encode() + // Successful encryption with not nil payload + err = encryptMsg(ikeMsg, ikeSAKey, message.Role_Responder) require.NoError(t, err) - - ikeMessage, err = decryptMsg( - rawMsg, ikeMessage, ikeSAKey, message.Role_Responder) - require.NoError(t, err) - require.Equal(t, ikePayloads, ikeMessage.Payloads) + expectPayload := message.IKEPayloadContainer{ + &message.Encrypted{ + NextPayload: uint8(message.NoNext), + EncryptedData: []byte{ + 0xa2, 0xfb, 0xbc, 0xdd, 0xd3, 0x9a, 0xda, 0xdd, + 0x67, 0x10, 0xbc, 0x38, 0x33, 0xc0, 0x23, 0x72, + 0xcd, 0xb2, 0xd8, 0xbd, 0x52, 0x64, 0xb4, 0xfe, + 0x07, 0x2c, 0x53, 0x18, 0x69, 0x0a, 0x89, 0x1d, + 0x23, 0x29, 0x0b, 0x19, 0xb2, 0x77, 0xfe, 0x54, + 0x96, 0x25, 0x2c, 0x86, 0x3f, 0x6b, 0x42, 0xaa, + 0x7a, 0x9e, 0x24, 0x69, 0x0a, 0xb5, 0xea, 0xcb, + 0x88, 0x65, 0xca, 0x1a, 0xf0, 0xd0, 0xc9, 0xbb, + 0xbd, 0xa2, 0xd9, 0x9b, 0x22, 0x76, 0x76, 0x7c, + 0x80, 0x84, 0xd2, 0xb4, + }, + }, + } + require.Equal(t, expectPayload[0].(*message.Encrypted).EncryptedData, + ikeMsg.Payloads[0].(*message.Encrypted).EncryptedData) // IKE Security Association is nil - err = encryptMsg(ikeMessage, nil, message.Role_Initiator) + err = encryptMsg(ikeMsg, nil, message.Role_Initiator) require.Error(t, err) - // No IKE payload to be encrypted - ikeMessage.Payloads.Reset() - err = encryptMsg(ikeMessage, ikeSAKey, message.Role_Initiator) - require.Error(t, err) - ikeMessage.Payloads = ikePayloads - // Response IKE Message is nil err = encryptMsg(nil, ikeSAKey, message.Role_Initiator) require.Error(t, err) // No integrity algorithm specified ikeSAKey.IntegInfo = nil - err = encryptMsg(ikeMessage, ikeSAKey, message.Role_Initiator) + err = encryptMsg(ikeMsg, ikeSAKey, message.Role_Initiator) require.Error(t, err) ikeSAKey.IntegInfo = integrityAlgorithm // No encryption algorithm specified ikeSAKey.EncrInfo = nil - err = encryptMsg(ikeMessage, ikeSAKey, message.Role_Initiator) + err = encryptMsg(ikeMsg, ikeSAKey, message.Role_Initiator) require.Error(t, err) ikeSAKey.EncrInfo = encryptionAlgorithm // No responder's integrity key ikeSAKey.Integ_r = nil - err = encryptMsg(ikeMessage, ikeSAKey, message.Role_Initiator) + err = encryptMsg(ikeMsg, ikeSAKey, message.Role_Initiator) require.Error(t, err) ikeSAKey.Integ_r = integ_r // No responder's encryption key ikeSAKey.Encr_r = nil - err = encryptMsg(ikeMessage, ikeSAKey, message.Role_Initiator) + err = encryptMsg(ikeMsg, ikeSAKey, message.Role_Initiator) require.Error(t, err) + + // Successful encryption with nil payload + iv, err = hex.DecodeString("95b0f4844980f4aa28861a0f11253061") + require.NoError(t, err) + + padding, err = hex.DecodeString("b78db03d231f014db091cb5214ed7b0f") + require.NoError(t, err) + + sk_ei, err = hex.DecodeString( + "3d3c6a1f1c693acf223aedf30ac81ae4fcd21c7e6fcefdd74280842d7feefd10") + require.NoError(t, err) + block, err = aes.NewCipher(sk_ei) + require.NoError(t, err) + ikeSAKey.Encr_i = &encr.EncrAesCbcCrypto{ + Block: block, + Iv: iv, + Padding: padding, + } + + sk_er, err = hex.DecodeString( + "577462e5d72cced94747c2742866d3ec5ed2ca53cf05eb59bfb88998a66c279a") + require.NoError(t, err) + block, err = aes.NewCipher(sk_er) + require.NoError(t, err) + ikeSAKey.Encr_r = &encr.EncrAesCbcCrypto{ + Block: block, + Iv: iv, + Padding: padding, + } + + sk_ai, err = hex.DecodeString( + "89a2b8789cc33333b01d26eaf4529f22a3420e24") + require.NoError(t, err) + ikeSAKey.Integ_i = ikeSAKey.IntegInfo.Init(sk_ai) + + sk_ar, err = hex.DecodeString( + "02f3ce7b78d16bd12b9f0b462ea823b9c67cc824") + require.NoError(t, err) + ikeSAKey.Integ_r = ikeSAKey.IntegInfo.Init(sk_ar) + ikeMsg = &message.IKEMessage{ + IKEHeader: &message.IKEHeader{ + InitiatorSPI: 0x172eb78b61479973, + ResponderSPI: 0x7fff512ecf965300, + NextPayload: uint8(message.NoNext), + MajorVersion: 0x2, + MinorVersion: 0x0, + ExchangeType: message.INFORMATIONAL, + Flags: 0x08, + MessageID: 0x02, + }, + Payloads: message.IKEPayloadContainer{}, + } + err = encryptMsg(ikeMsg, ikeSAKey, message.Role_Initiator) + require.NoError(t, err) + + nilPayload := message.IKEPayloadContainer{ + &message.Encrypted{ + NextPayload: uint8(message.NoNext), + EncryptedData: []byte{ + 0x95, 0xb0, 0xf4, 0x84, 0x49, 0x80, 0xf4, 0xaa, + 0x28, 0x86, 0x1a, 0x0f, 0x11, 0x25, 0x30, 0x61, + 0xf2, 0x6c, 0x08, 0x2f, 0x44, 0x36, 0x8b, 0x76, + 0x94, 0x3f, 0xd6, 0xee, 0x38, 0xe5, 0x48, 0xe8, + 0x90, 0xd8, 0xc6, 0x2f, 0x5e, 0xbe, 0xbd, 0x23, + 0x45, 0x79, 0x3f, 0x7f, + }, + }, + } + require.Equal(t, nilPayload[0].(*message.Encrypted).EncryptedData, + ikeMsg.Payloads[0].(*message.Encrypted).EncryptedData) } func TestVerifyIntegrity(t *testing.T) { diff --git a/security/dh/dh.go b/security/dh/dh.go index a32dfc0..50d9a66 100644 --- a/security/dh/dh.go +++ b/security/dh/dh.go @@ -6,6 +6,11 @@ import ( "github.com/free5gc/ike/message" ) +const ( + DH_1024_BIT_MODP string = "DH_1024_BIT_MODP" + DH_2048_BIT_MODP string = "DH_2048_BIT_MODP" +) + var ( dhString map[uint16]func(uint16, uint16, []byte) string dhTypes map[string]DHType @@ -22,25 +27,25 @@ func init() { var factor, generator *big.Int - // Group 2: DH_1024_BIT_MODP + // Group 2: Dh1024BitModp factor, ok := new(big.Int).SetString(Group2PrimeString, 16) if !ok { panic("IKE Diffie Hellman Group failed to init.") } generator = new(big.Int).SetUint64(Group2Generator) - dhTypes[string_DH_1024_BIT_MODP] = &DH_1024_BIT_MODP{ + dhTypes[DH_1024_BIT_MODP] = &Dh1024BitModp{ factor: factor, generator: generator, factorBytesLength: len(factor.Bytes()), } - // Group 14: DH_2048_BIT_MODP + // Group 14: DH2048BitModp factor, ok = new(big.Int).SetString(Group14PrimeString, 16) if !ok { panic("IKE Diffie Hellman Group failed to init.") } generator = new(big.Int).SetUint64(Group14Generator) - dhTypes[string_DH_2048_BIT_MODP] = &DH_2048_BIT_MODP{ + dhTypes[DH_2048_BIT_MODP] = &DH2048BitModp{ factor: factor, generator: generator, factorBytesLength: len(factor.Bytes()), diff --git a/security/dh/dh_1024_bit_modp.go b/security/dh/dh_1024_bit_modp.go index 69bf0db..e63d311 100644 --- a/security/dh/dh_1024_bit_modp.go +++ b/security/dh/dh_1024_bit_modp.go @@ -7,7 +7,6 @@ import ( ) const ( - string_DH_1024_BIT_MODP string = "DH_1024_BIT_MODP" // Parameters Group2PrimeString string = "FFFFFFFFFFFFFFFFC90FDAA22168C234" + "C4C6628B80DC1CD129024E088A67CC74" + @@ -21,33 +20,33 @@ const ( ) func toString_DH_1024_BIT_MODP(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_DH_1024_BIT_MODP + return DH_1024_BIT_MODP } -var _ DHType = &DH_1024_BIT_MODP{} +var _ DHType = &Dh1024BitModp{} -type DH_1024_BIT_MODP struct { +type Dh1024BitModp struct { factor *big.Int generator *big.Int factorBytesLength int } -func (t *DH_1024_BIT_MODP) TransformID() uint16 { +func (t *Dh1024BitModp) TransformID() uint16 { return message.DH_1024_BIT_MODP } -func (t *DH_1024_BIT_MODP) getAttribute() (bool, uint16, uint16, []byte) { +func (t *Dh1024BitModp) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *DH_1024_BIT_MODP) GetSharedKey(secret, peerPublicValue *big.Int) []byte { +func (t *Dh1024BitModp) GetSharedKey(secret, peerPublicValue *big.Int) []byte { sharedKey := new(big.Int).Exp(peerPublicValue, secret, t.factor).Bytes() prependZero := make([]byte, t.factorBytesLength-len(sharedKey)) sharedKey = append(prependZero, sharedKey...) return sharedKey } -func (t *DH_1024_BIT_MODP) GetPublicValue(secret *big.Int) []byte { +func (t *Dh1024BitModp) GetPublicValue(secret *big.Int) []byte { localPublicValue := new(big.Int).Exp(t.generator, secret, t.factor).Bytes() prependZero := make([]byte, t.factorBytesLength-len(localPublicValue)) localPublicValue = append(prependZero, localPublicValue...) diff --git a/security/dh/dh_2048_bit_modp.go b/security/dh/dh_2048_bit_modp.go index ba39c42..b7f525c 100644 --- a/security/dh/dh_2048_bit_modp.go +++ b/security/dh/dh_2048_bit_modp.go @@ -7,7 +7,6 @@ import ( ) const ( - string_DH_2048_BIT_MODP string = "DH_2048_BIT_MODP" // Parameters Group14PrimeString string = "FFFFFFFFFFFFFFFFC90FDAA22168C234" + "C4C6628B80DC1CD129024E088A67CC74" + @@ -29,33 +28,33 @@ const ( ) func toString_DH_2048_BIT_MODP(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_DH_2048_BIT_MODP + return DH_2048_BIT_MODP } -var _ DHType = &DH_2048_BIT_MODP{} +var _ DHType = &DH2048BitModp{} -type DH_2048_BIT_MODP struct { +type DH2048BitModp struct { factor *big.Int generator *big.Int factorBytesLength int } -func (t *DH_2048_BIT_MODP) TransformID() uint16 { +func (t *DH2048BitModp) TransformID() uint16 { return message.DH_2048_BIT_MODP } -func (t *DH_2048_BIT_MODP) getAttribute() (bool, uint16, uint16, []byte) { +func (t *DH2048BitModp) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *DH_2048_BIT_MODP) GetSharedKey(secret, peerPublicValue *big.Int) []byte { +func (t *DH2048BitModp) GetSharedKey(secret, peerPublicValue *big.Int) []byte { sharedKey := new(big.Int).Exp(peerPublicValue, secret, t.factor).Bytes() prependZero := make([]byte, t.factorBytesLength-len(sharedKey)) sharedKey = append(prependZero, sharedKey...) return sharedKey } -func (t *DH_2048_BIT_MODP) GetPublicValue(secret *big.Int) []byte { +func (t *DH2048BitModp) GetPublicValue(secret *big.Int) []byte { localPublicValue := new(big.Int).Exp(t.generator, secret, t.factor).Bytes() prependZero := make([]byte, t.factorBytesLength-len(localPublicValue)) localPublicValue = append(prependZero, localPublicValue...) diff --git a/security/encr/encr.go b/security/encr/encr.go index d80981d..da94874 100644 --- a/security/encr/encr.go +++ b/security/encr/encr.go @@ -22,26 +22,26 @@ func init() { // ENCR Types encrTypes = make(map[string]ENCRType) - encrTypes[string_ENCR_AES_CBC_128] = &ENCR_AES_CBC{ + encrTypes[ENCR_AES_CBC_128] = &EncrAesCbc{ keyLength: 16, } - encrTypes[string_ENCR_AES_CBC_192] = &ENCR_AES_CBC{ + encrTypes[ENCR_AES_CBC_192] = &EncrAesCbc{ keyLength: 24, } - encrTypes[string_ENCR_AES_CBC_256] = &ENCR_AES_CBC{ + encrTypes[ENCR_AES_CBC_256] = &EncrAesCbc{ keyLength: 32, } // ENCR Kernel Types encrKTypes = make(map[string]ENCRKType) - encrKTypes[string_ENCR_AES_CBC_128] = &ENCR_AES_CBC{ + encrKTypes[ENCR_AES_CBC_128] = &EncrAesCbc{ keyLength: 16, } - encrKTypes[string_ENCR_AES_CBC_192] = &ENCR_AES_CBC{ + encrKTypes[ENCR_AES_CBC_192] = &EncrAesCbc{ keyLength: 24, } - encrKTypes[string_ENCR_AES_CBC_256] = &ENCR_AES_CBC{ + encrKTypes[ENCR_AES_CBC_256] = &EncrAesCbc{ keyLength: 32, } } diff --git a/security/encr/encr_aes_cbc.go b/security/encr/encr_aes_cbc.go index b2d448d..2387f0c 100644 --- a/security/encr/encr_aes_cbc.go +++ b/security/encr/encr_aes_cbc.go @@ -14,20 +14,20 @@ import ( ) const ( - string_ENCR_AES_CBC_128 string = "ENCR_AES_CBC_128" - string_ENCR_AES_CBC_192 string = "ENCR_AES_CBC_192" - string_ENCR_AES_CBC_256 string = "ENCR_AES_CBC_256" + ENCR_AES_CBC_128 string = "ENCR_AES_CBC_128" + ENCR_AES_CBC_192 string = "ENCR_AES_CBC_192" + ENCR_AES_CBC_256 string = "ENCR_AES_CBC_256" ) func toString_ENCR_AES_CBC(attrType uint16, intValue uint16, bytesValue []byte) string { if attrType == message.AttributeTypeKeyLength { switch intValue { case 128: - return string_ENCR_AES_CBC_128 + return ENCR_AES_CBC_128 case 192: - return string_ENCR_AES_CBC_192 + return ENCR_AES_CBC_192 case 256: - return string_ENCR_AES_CBC_256 + return ENCR_AES_CBC_256 default: return "" } @@ -37,19 +37,19 @@ func toString_ENCR_AES_CBC(attrType uint16, intValue uint16, bytesValue []byte) } var ( - _ ENCRType = &ENCR_AES_CBC{} - _ ENCRKType = &ENCR_AES_CBC{} + _ ENCRType = &EncrAesCbc{} + _ ENCRKType = &EncrAesCbc{} ) -type ENCR_AES_CBC struct { +type EncrAesCbc struct { keyLength int } -func (t *ENCR_AES_CBC) TransformID() uint16 { +func (t *EncrAesCbc) TransformID() uint16 { return message.ENCR_AES_CBC } -func (t *ENCR_AES_CBC) getAttribute() (bool, uint16, uint16, []byte, error) { +func (t *EncrAesCbc) getAttribute() (bool, uint16, uint16, []byte, error) { keyLengthBits := t.keyLength * 8 if keyLengthBits < 0 || keyLengthBits > 0xFFFF { return false, 0, 0, nil, errors.Errorf("key length exceeds uint16 maximum value: %v", keyLengthBits) @@ -57,73 +57,94 @@ func (t *ENCR_AES_CBC) getAttribute() (bool, uint16, uint16, []byte, error) { return true, message.AttributeTypeKeyLength, uint16(keyLengthBits), nil, nil } -func (t *ENCR_AES_CBC) GetKeyLength() int { +func (t *EncrAesCbc) GetKeyLength() int { return t.keyLength } -func (t *ENCR_AES_CBC) NewCrypto(key []byte) (ikeCrypto.IKECrypto, error) { +func (t *EncrAesCbc) NewCrypto(key []byte) (ikeCrypto.IKECrypto, error) { var err error - encr := new(ENCR_AES_CBC_Crypto) + encr := new(EncrAesCbcCrypto) if len(key) != t.keyLength { - return nil, errors.Errorf("ENCR_AES_CBC init error: Get unexpected key length") + return nil, errors.Errorf("EncrAesCbc init error: Get unexpected key length") } - if encr.block, err = aes.NewCipher(key); err != nil { - return nil, errors.Wrapf(err, "ENCR_AES_CBC init: Error occur when create new cipher: ") + + if encr.Block, err = aes.NewCipher(key); err != nil { + return nil, errors.Wrapf(err, "EncrAesCbc init: Error occur when create new cipher: ") } else { return encr, nil } } -var _ ikeCrypto.IKECrypto = &ENCR_AES_CBC_Crypto{} +var _ ikeCrypto.IKECrypto = &EncrAesCbcCrypto{} -type ENCR_AES_CBC_Crypto struct { - block cipher.Block +type EncrAesCbcCrypto struct { + Block cipher.Block + Iv []byte // initializationVector + Padding []byte } -func (encr *ENCR_AES_CBC_Crypto) Encrypt(plainText []byte) ([]byte, error) { +func (encr *EncrAesCbcCrypto) Encrypt(plainText []byte) ([]byte, error) { + var err error + // Padding message - plainText = lib.PKCS7Padding(plainText, aes.BlockSize) - plainText[len(plainText)-1]-- + if encr.Padding == nil { + plainText, err = lib.PKCS7Padding(plainText, aes.BlockSize) + if err != nil { + return nil, errors.Wrapf(err, "Encr Encrypt()") + } + } else { + plainText = append(plainText, encr.Padding...) + } // Slice cipherText := make([]byte, aes.BlockSize+len(plainText)) - initializationVector := cipherText[:aes.BlockSize] - - // IV - _, err := io.ReadFull(rand.Reader, initializationVector) - if err != nil { - return nil, errors.Errorf("Read random initialization vector failed") + var initializationVector []byte + if encr.Iv == nil { + initializationVector = cipherText[:aes.BlockSize] + // IV + _, err = io.ReadFull(rand.Reader, initializationVector) + if err != nil { + return nil, errors.Errorf("Read random initialization vector failed") + } + } else { + copy(cipherText[:aes.BlockSize], encr.Iv) + initializationVector = encr.Iv } // Encryption - cbcBlockMode := cipher.NewCBCEncrypter(encr.block, initializationVector) // #nosec G407 + cbcBlockMode := cipher.NewCBCEncrypter(encr.Block, initializationVector) // #nosec G407 cbcBlockMode.CryptBlocks(cipherText[aes.BlockSize:], plainText) return cipherText, nil } -func (encr *ENCR_AES_CBC_Crypto) Decrypt(cipherText []byte) ([]byte, error) { +func (encr *EncrAesCbcCrypto) Decrypt(cipherText []byte) ([]byte, error) { // Check if len(cipherText) < aes.BlockSize { - return nil, errors.Errorf("ENCR_AES_CBC_Crypto: Length of cipher text is too short to decrypt") + return nil, errors.Errorf("EncrAesCbcCrypto: Length of cipher text is too short to decrypt") + } + + var initializationVector []byte + if encr.Iv == nil { + initializationVector = cipherText[:aes.BlockSize] + } else { + initializationVector = encr.Iv } - initializationVector := cipherText[:aes.BlockSize] encryptedMessage := cipherText[aes.BlockSize:] if len(encryptedMessage)%aes.BlockSize != 0 { - return nil, errors.Errorf("ENCR_AES_CBC_Crypto: Cipher text is not a multiple of block size") + return nil, errors.Errorf("EncrAesCbcCrypto: Cipher text is not a multiple of block size") } // Slice plainText := make([]byte, len(encryptedMessage)) // Decryption - cbcBlockMode := cipher.NewCBCDecrypter(encr.block, initializationVector) // #nosec G407 + cbcBlockMode := cipher.NewCBCDecrypter(encr.Block, initializationVector) // #nosec G407 cbcBlockMode.CryptBlocks(plainText, encryptedMessage) // fmt.Printf("Decrypted content:\n%s", hex.Dump(plainText)) - // Remove padding padding := int(plainText[len(plainText)-1]) + 1 plainText = plainText[:len(plainText)-padding] diff --git a/security/encr/encr_aes_cbc128_test.go b/security/encr/encr_aes_cbc128_test.go new file mode 100644 index 0000000..f73a767 --- /dev/null +++ b/security/encr/encr_aes_cbc128_test.go @@ -0,0 +1,173 @@ +package encr + +import ( + "crypto/aes" + "crypto/cipher" + "testing" + + "github.com/stretchr/testify/require" +) + +var ( + sk_ei_128 = []byte{ + 0x54, 0x5e, 0x6b, 0x26, 0x57, 0x68, 0x0e, 0x51, + 0xc8, 0x87, 0x1e, 0xd9, 0xf9, 0x1b, 0x4b, 0xfe, + } + iv_nil_128 = []byte{ + 0xdb, 0xe6, 0xdb, 0xac, 0x7a, 0x0e, 0x31, 0x94, + 0x5d, 0x7c, 0x3d, 0x36, 0xc4, 0x4e, 0x4e, 0x59, + } + padding_nil_128 = []byte{ + 0x0e, 0x04, 0x20, 0x39, 0x6b, 0xf1, 0x5b, 0x53, + 0x06, 0x83, 0x3c, 0x2a, 0x51, 0xae, 0xd8, 0x0f, + } + cipherText_nil_128 = []byte{ + 0xdb, 0xe6, 0xdb, 0xac, 0x7a, 0x0e, 0x31, 0x94, + 0x5d, 0x7c, 0x3d, 0x36, 0xc4, 0x4e, 0x4e, 0x59, + 0x6e, 0xab, 0x02, 0xad, 0xf9, 0x86, 0x3a, 0x6a, + 0x05, 0x35, 0x8a, 0x02, 0x6e, 0x69, 0x03, 0xd7, + } + iv_128 = []byte{ + 0x10, 0x01, 0xaa, 0x50, 0xdc, 0x12, 0xa7, 0x19, + 0x04, 0xe8, 0xd8, 0x96, 0x29, 0x10, 0x37, 0x87, + } + padding_128 = []byte{ + 0x6c, 0x7f, 0x4f, 0x78, 0x9e, 0x8e, 0x84, 0x07, + } + plainText_128 = []byte{ + 0x29, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x0a, 0x00, 0xca, 0x24, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x40, 0x00, 0x27, 0x00, 0x00, 0x0c, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x5e, + 0x21, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x00, + 0xae, 0xdf, 0xef, 0xe3, 0x75, 0x46, 0x6c, 0x42, + 0x32, 0x5c, 0xa4, 0xbe, 0x6f, 0x9d, 0x0e, 0xb8, + 0xb4, 0xb1, 0xde, 0x6c, 0x2c, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x28, 0x01, 0x03, 0x04, 0x03, + 0xc6, 0x74, 0x91, 0x8a, 0x03, 0x00, 0x00, 0x0c, + 0x01, 0x00, 0x00, 0x0c, 0x80, 0x0e, 0x00, 0x80, + 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, + 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0xff, + 0x29, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, + 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0xff, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x0c, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0x0a, 0x64, 0x64, 0x7c, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x10, 0x16, 0xfd, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x10, 0x06, 0xfd, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x1f, 0xff, 0xff, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x11, 0x00, 0x01, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0x0a, 0x64, 0x64, 0x0c, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x10, 0x3d, 0x01, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x10, 0x3e, 0x01, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x14, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x21, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x24, + } + cipherText_128 = []byte{ + 0x10, 0x01, 0xaa, 0x50, 0xdc, 0x12, 0xa7, 0x19, + 0x04, 0xe8, 0xd8, 0x96, 0x29, 0x10, 0x37, 0x87, + 0xf0, 0x62, 0x84, 0x67, 0xdb, 0xda, 0x9b, 0x0c, + 0x64, 0x70, 0x29, 0xd3, 0x67, 0xb4, 0x40, 0xa1, + 0x7a, 0x99, 0x99, 0x12, 0x87, 0x75, 0xdd, 0x4c, + 0xc0, 0x5f, 0x9e, 0x34, 0xfc, 0xc7, 0x64, 0x8e, + 0x09, 0x6e, 0xeb, 0x6f, 0x67, 0xc8, 0x07, 0xe8, + 0xf1, 0xf3, 0x0b, 0xc4, 0xb0, 0x0a, 0x67, 0x6c, + 0x9d, 0x86, 0x7b, 0x87, 0xe6, 0x4b, 0x64, 0x14, + 0x73, 0xa2, 0x9b, 0xc2, 0x45, 0x78, 0xfd, 0x6d, + 0xa8, 0x75, 0x25, 0xbc, 0xa8, 0x65, 0x94, 0x27, + 0x9a, 0x3a, 0xb3, 0xe6, 0x71, 0xe3, 0x32, 0x01, + 0x69, 0x37, 0x16, 0x23, 0xa7, 0xaa, 0xd6, 0x8f, + 0x52, 0xf2, 0x10, 0x03, 0xe6, 0x6a, 0xba, 0x57, + 0x87, 0x7c, 0xad, 0xed, 0xe6, 0xe0, 0xc6, 0xa5, + 0xc3, 0xb3, 0xac, 0xf6, 0x83, 0xb4, 0x78, 0xcb, + 0x94, 0x91, 0x6b, 0xb0, 0xcd, 0xa1, 0x17, 0xb5, + 0x68, 0xfd, 0x17, 0x23, 0x9f, 0xbb, 0x31, 0xc1, + 0x5b, 0xb4, 0x12, 0xf3, 0x3c, 0xd7, 0x2f, 0xe8, + 0x2b, 0xba, 0x1d, 0x7f, 0x74, 0xf1, 0x01, 0x42, + 0x65, 0xbe, 0x7d, 0x4e, 0x4c, 0x56, 0x22, 0x4a, + 0x7b, 0x38, 0x58, 0x7d, 0x24, 0xa4, 0xed, 0x4f, + 0x7e, 0xa0, 0x12, 0x84, 0x90, 0x7f, 0x71, 0x90, + 0x0f, 0x12, 0x7d, 0x88, 0xf5, 0x6d, 0x3b, 0x31, + 0x41, 0x07, 0x39, 0x6d, 0xe5, 0xfa, 0x32, 0x2b, + 0xdf, 0xbf, 0x6b, 0xe7, 0xdb, 0xef, 0xe0, 0x8d, + 0x61, 0xf8, 0x3f, 0x74, 0x61, 0xe0, 0x50, 0x04, + 0xb3, 0x80, 0xd2, 0xb0, 0x03, 0x53, 0x44, 0xa1, + 0x43, 0xa4, 0xaf, 0xaa, 0x57, 0xda, 0x80, 0xdd, + 0x21, 0xa1, 0x13, 0xef, 0x4c, 0x04, 0x8e, 0xd5, + 0xf4, 0x65, 0x96, 0xe1, 0x30, 0xc6, 0x9a, 0x57, + 0xd8, 0x9d, 0xf2, 0x22, 0x94, 0x6c, 0x62, 0xf5, + 0xb9, 0x34, 0x9a, 0x37, 0x2e, 0xaf, 0xb6, 0xb8, + 0x24, 0xaa, 0x95, 0xfa, 0x6e, 0x99, 0xfa, 0x2d, + 0x79, 0xf2, 0x38, 0xc8, 0xfb, 0xbf, 0xf9, 0x2b, + 0x42, 0xed, 0xcc, 0x54, 0xbf, 0x4e, 0x97, 0x77, + 0xfa, 0x9a, 0xf8, 0x3c, 0x36, 0xba, 0xb4, 0x76, + 0x37, 0x66, 0x94, 0xab, 0x9c, 0x8b, 0x56, 0xc6, + } +) + +func TestEncrypt_128(t *testing.T) { + var sk EncrAesCbcCrypto + var block cipher.Block + var err error + var cipher []byte + + block, err = aes.NewCipher(sk_ei_128) + require.NoError(t, err) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_nil_128, + Padding: padding_nil_128, + } + require.NoError(t, err) + cipher, err = sk.Encrypt(nil) + require.NoError(t, err) + require.Equal(t, cipherText_nil_128, cipher) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_128, + Padding: padding_128, + } + require.NoError(t, err) + cipher, err = sk.Encrypt(plainText_128) + require.NoError(t, err) + require.Equal(t, cipherText_128, cipher) +} + +func TestDecrypt_128(t *testing.T) { + var sk EncrAesCbcCrypto + var err error + var block cipher.Block + var plain []byte + + block, err = aes.NewCipher(sk_ei_128) + require.NoError(t, err) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_nil_128, + Padding: padding_nil_128, + } + plain, err = sk.Decrypt(cipherText_nil_128) + require.NoError(t, err) + testnil := make([]byte, 0) + require.Equal(t, testnil, plain) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_128, + Padding: padding_128, + } + plain, err = sk.Decrypt(cipherText_128) + require.NoError(t, err) + require.Equal(t, plainText_128, plain) +} diff --git a/security/encr/encr_aes_cbc192_test.go b/security/encr/encr_aes_cbc192_test.go new file mode 100644 index 0000000..cf79756 --- /dev/null +++ b/security/encr/encr_aes_cbc192_test.go @@ -0,0 +1,172 @@ +package encr + +import ( + "crypto/aes" + "crypto/cipher" + "testing" + + "github.com/stretchr/testify/require" +) + +var ( + sk_ei_196 = []byte{ + 0xa0, 0x0a, 0x7b, 0xb9, 0x2b, 0x05, 0xf9, 0x34, + 0x92, 0x15, 0x72, 0xcd, 0xca, 0x00, 0xa0, 0xdf, + 0x06, 0x4b, 0xba, 0xd3, 0x3e, 0x15, 0x15, 0x4e, + } + iv_nil_196 = []byte{ + 0x2a, 0xe6, 0xef, 0x86, 0xa9, 0x22, 0x92, 0x98, + 0x2f, 0xa5, 0x66, 0x24, 0x10, 0xad, 0x5a, 0x4b, + } + padding_nil_196 = []byte{ + 0xa4, 0x9b, 0x11, 0x3a, 0x38, 0xca, 0x76, 0x59, + 0xe6, 0x0b, 0x68, 0x3d, 0x80, 0x96, 0x3a, 0x0f, + } + cipherText_nil_196 = []byte{ + 0x2a, 0xe6, 0xef, 0x86, 0xa9, 0x22, 0x92, 0x98, + 0x2f, 0xa5, 0x66, 0x24, 0x10, 0xad, 0x5a, 0x4b, + 0x72, 0xe6, 0x5a, 0x40, 0x6d, 0xc6, 0xb8, 0xaf, + 0x11, 0xc4, 0xbc, 0xb1, 0x31, 0x35, 0xc5, 0x19, + } + iv_196 = []byte{ + 0x51, 0x8d, 0xb4, 0x69, 0x19, 0x5a, 0xca, 0x2e, + 0x08, 0x9d, 0xa0, 0xcd, 0x0d, 0xbc, 0x56, 0x72, + } + padding_196 = []byte{ + 0xd5, 0x4e, 0x5b, 0x27, 0xf4, 0xd6, 0xa3, 0x07, + } + plainText_196 = []byte{ + 0x29, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x0a, 0x00, 0xca, 0x24, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x40, 0x00, 0x27, 0x00, 0x00, 0x0c, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x5e, + 0x21, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x00, + 0xfe, 0x80, 0x67, 0xe4, 0x8a, 0xe2, 0x3e, 0x60, + 0x21, 0x7b, 0x0c, 0x91, 0xee, 0x8f, 0xef, 0x76, + 0xc9, 0x10, 0x9a, 0xce, 0x2c, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x28, 0x01, 0x03, 0x04, 0x03, + 0xcb, 0xf8, 0xd2, 0xd7, 0x03, 0x00, 0x00, 0x0c, + 0x01, 0x00, 0x00, 0x0c, 0x80, 0x0e, 0x00, 0xc0, + 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, + 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0xff, + 0x29, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, + 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0xff, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x0c, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0x0a, 0x64, 0x64, 0x7c, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x10, 0x16, 0xfd, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x10, 0x06, 0xfd, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x1f, 0xff, 0xff, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x11, 0x00, 0x01, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0x0a, 0x64, 0x64, 0x0c, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x10, 0x3d, 0x01, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x10, 0x3e, 0x01, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x14, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x21, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x24, + } + cipherText_196 = []byte{ + 0x51, 0x8d, 0xb4, 0x69, 0x19, 0x5a, 0xca, 0x2e, + 0x08, 0x9d, 0xa0, 0xcd, 0x0d, 0xbc, 0x56, 0x72, + 0xe0, 0x63, 0x6f, 0x4e, 0xa9, 0xf9, 0x90, 0xfa, + 0xc0, 0x0a, 0xbf, 0xb7, 0x9d, 0x61, 0x99, 0x19, + 0xb1, 0xca, 0x77, 0x53, 0xed, 0xbe, 0x74, 0x73, + 0x3d, 0x24, 0x33, 0x67, 0x96, 0xa9, 0x47, 0x75, + 0x8e, 0xcb, 0x21, 0x95, 0xb4, 0x40, 0x6e, 0x98, + 0xb8, 0x6d, 0x68, 0x6f, 0x58, 0x8e, 0x4a, 0x7b, + 0x4d, 0x34, 0x3f, 0x19, 0xf6, 0x5d, 0xb9, 0x71, + 0x4b, 0xcd, 0x5c, 0x14, 0x70, 0xb9, 0x60, 0x17, + 0x25, 0xa1, 0x5a, 0x4f, 0x19, 0xcb, 0xe4, 0xf3, + 0x80, 0x97, 0x55, 0xa4, 0xcb, 0x2e, 0x8f, 0x46, + 0xdd, 0x16, 0xf2, 0x15, 0x4e, 0x4a, 0x9c, 0xe1, + 0x4d, 0x37, 0x33, 0xfc, 0x83, 0xbe, 0x63, 0xfd, + 0xb3, 0xf6, 0xd8, 0x03, 0x30, 0x82, 0x7b, 0xe9, + 0xc7, 0x1c, 0xc7, 0x5f, 0x8a, 0x5c, 0x79, 0xaf, + 0xfa, 0x14, 0x3e, 0xd7, 0xe4, 0xa6, 0x16, 0xf3, + 0xb7, 0xd0, 0xe2, 0xc4, 0x94, 0x13, 0x27, 0x9e, + 0x30, 0xda, 0x71, 0x33, 0x65, 0x47, 0x6f, 0xc4, + 0xe5, 0xd0, 0x8f, 0x1a, 0xf6, 0x8f, 0x26, 0xfb, + 0x57, 0x0f, 0x8c, 0xdd, 0x9b, 0x22, 0xc4, 0x3f, + 0x4d, 0x84, 0x6a, 0xd6, 0x17, 0xe3, 0xbb, 0x89, + 0x45, 0xdf, 0x7e, 0x59, 0xba, 0xcf, 0xb2, 0x42, + 0x2d, 0x01, 0x9d, 0x64, 0xbc, 0xe8, 0x7b, 0x8a, + 0xa9, 0xd8, 0xc6, 0x9d, 0x93, 0xc2, 0x9f, 0x94, + 0x0f, 0x3c, 0xea, 0x3f, 0xd5, 0x35, 0x01, 0x65, + 0x3b, 0x17, 0x7e, 0xbe, 0x51, 0x18, 0xa3, 0x09, + 0x4b, 0x43, 0xb6, 0xea, 0x11, 0xd3, 0xd8, 0xc1, + 0x7a, 0x8e, 0x1b, 0x31, 0x45, 0xbe, 0xfa, 0x1e, + 0x24, 0xf1, 0x13, 0x4b, 0x5a, 0x90, 0x2e, 0x2c, + 0x9b, 0x64, 0xb6, 0xcd, 0x32, 0xa7, 0x5c, 0xce, + 0xa5, 0x9a, 0xab, 0xf8, 0xc9, 0x4c, 0xbe, 0xc7, + 0xd6, 0xe3, 0x94, 0x50, 0x27, 0x65, 0x0f, 0x84, + 0x28, 0x64, 0xf8, 0x9f, 0x18, 0x87, 0x4d, 0xfe, + 0xe6, 0xee, 0x2f, 0x65, 0x6c, 0xbd, 0xcb, 0xd7, + 0x8a, 0x13, 0x47, 0x9f, 0x15, 0x39, 0x22, 0x70, + 0x28, 0x8c, 0x28, 0xc0, 0x99, 0x2e, 0x24, 0x17, + 0x33, 0xf8, 0xdf, 0xc8, 0x09, 0x78, 0x22, 0x50, + } +) + +func TestEncrypt_196(t *testing.T) { + var sk EncrAesCbcCrypto + var block cipher.Block + var err error + var cipher []byte + + block, err = aes.NewCipher(sk_ei_196) + require.NoError(t, err) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_nil_196, + Padding: padding_nil_196, + } + cipher, err = sk.Encrypt(nil) + require.NoError(t, err) + require.Equal(t, cipherText_nil_196, cipher) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_196, + Padding: padding_196, + } + cipher, err = sk.Encrypt(plainText_196) + require.NoError(t, err) + require.Equal(t, cipherText_196, cipher) +} + +func TestDecrypt_196(t *testing.T) { + var sk EncrAesCbcCrypto + var err error + var block cipher.Block + var plain []byte + + block, err = aes.NewCipher(sk_ei_196) + require.NoError(t, err) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_nil_196, + Padding: padding_nil_196, + } + plain, err = sk.Decrypt(cipherText_nil_196) + require.NoError(t, err) + testnil := make([]byte, 0) + require.Equal(t, testnil, plain) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_196, + Padding: padding_196, + } + plain, err = sk.Decrypt(cipherText_196) + require.NoError(t, err) + require.Equal(t, plainText_196, plain) +} diff --git a/security/encr/encr_aes_cbc256_test.go b/security/encr/encr_aes_cbc256_test.go new file mode 100644 index 0000000..bf76e8c --- /dev/null +++ b/security/encr/encr_aes_cbc256_test.go @@ -0,0 +1,173 @@ +package encr + +import ( + "crypto/aes" + "crypto/cipher" + "testing" + + "github.com/stretchr/testify/require" +) + +var ( + sk_ei_256 = []byte{ + 0x3d, 0x3c, 0x6a, 0x1f, 0x1c, 0x69, 0x3a, 0xcf, + 0x22, 0x3a, 0xed, 0xf3, 0x0a, 0xc8, 0x1a, 0xe4, + 0xfc, 0xd2, 0x1c, 0x7e, 0x6f, 0xce, 0xfd, 0xd7, + 0x42, 0x80, 0x84, 0x2d, 0x7f, 0xee, 0xfd, 0x10, + } + iv_nil_256 = []byte{ + 0x95, 0xb0, 0xf4, 0x84, 0x49, 0x80, 0xf4, 0xaa, + 0x28, 0x86, 0x1a, 0x0f, 0x11, 0x25, 0x30, 0x61, + } + padding_nil_256 = []byte{ + 0xb7, 0x8d, 0xb0, 0x3d, 0x23, 0x1f, 0x01, 0x4d, + 0xb0, 0x91, 0xcb, 0x52, 0x14, 0xed, 0x7b, 0x0f, + } + cipherText_nil_256 = []byte{ + 0x95, 0xb0, 0xf4, 0x84, 0x49, 0x80, 0xf4, 0xaa, + 0x28, 0x86, 0x1a, 0x0f, 0x11, 0x25, 0x30, 0x61, + 0xf2, 0x6c, 0x08, 0x2f, 0x44, 0x36, 0x8b, 0x76, + 0x94, 0x3f, 0xd6, 0xee, 0x38, 0xe5, 0x48, 0xe8, + } + iv_256 = []byte{ + 0xf1, 0x42, 0xeb, 0x54, 0x99, 0x07, 0x27, 0xc1, + 0xb8, 0x02, 0x30, 0x2e, 0xea, 0xb6, 0xfe, 0x1e, + } + padding_256 = []byte{ + 0xd3, 0xae, 0xca, 0x6b, 0x2f, 0x91, 0x5f, 0x07, + } + plainText_256 = []byte{ + 0x29, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x0a, 0x00, 0xca, 0x24, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x40, 0x00, 0x27, 0x00, 0x00, 0x0c, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x5e, + 0x21, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x00, + 0xc5, 0x25, 0x2b, 0x3b, 0x2f, 0x8d, 0xb9, 0x67, + 0xb8, 0xe0, 0x88, 0x05, 0x5c, 0x02, 0xd2, 0xe3, + 0xa3, 0xe2, 0x11, 0xb5, 0x2c, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x28, 0x01, 0x03, 0x04, 0x03, + 0xc6, 0xe6, 0x62, 0x17, 0x03, 0x00, 0x00, 0x0c, + 0x01, 0x00, 0x00, 0x0c, 0x80, 0x0e, 0x01, 0x00, + 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, + 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0xff, + 0x29, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x10, 0x00, 0x00, 0xff, 0xff, + 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0xff, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x0c, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0x0a, 0x64, 0x64, 0x7c, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x10, 0x16, 0xfd, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x10, 0x06, 0xfd, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x1f, 0xff, 0xff, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x11, 0x00, 0x01, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0x0a, 0x64, 0x64, 0x0c, + 0x29, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x0d, + 0xac, 0x10, 0x3d, 0x01, 0x29, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x40, 0x0d, 0xac, 0x10, 0x3e, 0x01, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x14, + 0x29, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x21, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x24, + } + cipherText_256 = []byte{ + 0xf1, 0x42, 0xeb, 0x54, 0x99, 0x07, 0x27, 0xc1, + 0xb8, 0x02, 0x30, 0x2e, 0xea, 0xb6, 0xfe, 0x1e, + 0x40, 0xf2, 0x5d, 0x95, 0x0e, 0x12, 0xba, 0xe0, + 0xc2, 0x42, 0x96, 0x7d, 0xa6, 0xa4, 0x05, 0xe3, + 0xaa, 0xcb, 0xd8, 0x16, 0x39, 0x6a, 0x89, 0x42, + 0xd6, 0xe7, 0x43, 0x3d, 0x54, 0x87, 0x6a, 0x8a, + 0x50, 0x8c, 0x7f, 0x8b, 0xfb, 0x2c, 0xf4, 0x18, + 0xf4, 0x77, 0x50, 0xb1, 0x85, 0x50, 0x2c, 0xab, + 0xa8, 0xfe, 0x46, 0x62, 0xd1, 0xdd, 0x6f, 0xd7, + 0xfa, 0xd7, 0xb0, 0x7e, 0xb6, 0x02, 0x05, 0x51, + 0xe7, 0xf7, 0xd7, 0xcd, 0xde, 0x4d, 0x8e, 0xbe, + 0xe0, 0xb8, 0xdc, 0x9e, 0xd9, 0xd6, 0x00, 0xc7, + 0x3d, 0xd2, 0xf4, 0xab, 0xa6, 0xc9, 0xe8, 0x04, + 0xf0, 0xff, 0x86, 0xa5, 0x6a, 0x71, 0x59, 0xe9, + 0xf3, 0x3f, 0xc3, 0x61, 0x0d, 0x61, 0x31, 0x24, + 0xfd, 0xf1, 0x96, 0x6d, 0xcc, 0x8e, 0xa5, 0x13, + 0x43, 0xa4, 0x5b, 0xbc, 0x60, 0x03, 0x6e, 0x2f, + 0x7e, 0xef, 0xea, 0x8b, 0x61, 0x84, 0x05, 0xeb, + 0xd3, 0xdf, 0xba, 0xbc, 0x56, 0xef, 0xa0, 0x0c, + 0x9e, 0x53, 0xfd, 0xd3, 0xa9, 0x3d, 0x4f, 0xb4, + 0xb9, 0xd5, 0x2a, 0xd6, 0xb2, 0xb2, 0x87, 0xdc, + 0x03, 0xd8, 0xb3, 0x59, 0xde, 0x12, 0x4e, 0x6b, + 0x0a, 0xdc, 0x5e, 0x34, 0xa1, 0xf9, 0xd7, 0xe0, + 0xc7, 0xca, 0xd9, 0xa1, 0x3c, 0x27, 0x1a, 0xc1, + 0xaa, 0x75, 0xc8, 0xa0, 0xd6, 0xfe, 0x89, 0x7b, + 0x74, 0xaf, 0xfd, 0xa5, 0x4b, 0xfd, 0x05, 0xd9, + 0x25, 0x3e, 0x18, 0xa4, 0xb7, 0xa9, 0xe7, 0x22, + 0x76, 0x57, 0x58, 0x64, 0x16, 0x9e, 0x8a, 0x38, + 0xdc, 0x87, 0x7f, 0x4f, 0x68, 0xab, 0x61, 0xd6, + 0x56, 0xe5, 0xa6, 0x94, 0x63, 0xb0, 0x67, 0xd9, + 0xbc, 0x74, 0x60, 0x53, 0x13, 0x1f, 0xe5, 0x8a, + 0x70, 0xaa, 0x7a, 0x8f, 0xf6, 0x0c, 0x86, 0xa6, + 0x56, 0xcf, 0x30, 0x97, 0x92, 0x48, 0x51, 0x01, + 0x40, 0xc9, 0x44, 0x3f, 0x80, 0x07, 0x62, 0x5e, + 0x20, 0x1e, 0x96, 0xd8, 0x9d, 0x60, 0x8f, 0xf5, + 0xab, 0xd3, 0xeb, 0x3e, 0x0f, 0x3b, 0xf5, 0x04, + 0x8d, 0xce, 0x8e, 0x63, 0x0a, 0x66, 0xb8, 0x9a, + 0xa7, 0x8e, 0x45, 0x27, 0x3b, 0xd2, 0xd3, 0xda, + } +) + +func TestEncrypt_256(t *testing.T) { + var sk EncrAesCbcCrypto + var block cipher.Block + var err error + var cipher []byte + + block, err = aes.NewCipher(sk_ei_256) + require.NoError(t, err) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_nil_256, + Padding: padding_nil_256, + } + cipher, err = sk.Encrypt(nil) + require.NoError(t, err) + require.Equal(t, cipherText_nil_256, cipher) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_256, + Padding: padding_256, + } + cipher, err = sk.Encrypt(plainText_256) + require.NoError(t, err) + require.Equal(t, cipherText_256, cipher) +} + +func TestDecrypt_256(t *testing.T) { + var sk EncrAesCbcCrypto + var err error + var block cipher.Block + var plain []byte + + block, err = aes.NewCipher(sk_ei_256) + require.NoError(t, err) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_nil_256, + Padding: padding_nil_256, + } + plain, err = sk.Decrypt(cipherText_nil_256) + require.NoError(t, err) + testnil := make([]byte, 0) + require.Equal(t, testnil, plain) + + sk = EncrAesCbcCrypto{ + Block: block, + Iv: iv_256, + Padding: padding_256, + } + plain, err = sk.Decrypt(cipherText_256) + require.NoError(t, err) + require.Equal(t, plainText_256, plain) +} diff --git a/security/esn/esn.go b/security/esn/esn.go index efff931..f48bd47 100644 --- a/security/esn/esn.go +++ b/security/esn/esn.go @@ -12,16 +12,16 @@ var ( ) const ( - string_ESN_ENABLE string = "ESN_ENABLE" - string_ESN_DISABLE string = "ESN_DISABLE" + String_ESN_ENABLE string = "ESN_ENABLE" + String_ESN_DISABLE string = "ESN_DISABLE" ) func toString_ESN_ENABLE(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_ESN_ENABLE + return String_ESN_ENABLE } func toString_ESN_DISABLE(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_ESN_DISABLE + return String_ESN_DISABLE } func init() { @@ -33,10 +33,10 @@ func init() { // ESN Types esnTypes = make(map[string]ESN) - esnTypes[string_ESN_ENABLE] = ESN{ + esnTypes[String_ESN_ENABLE] = ESN{ needESN: true, } - esnTypes[string_ESN_DISABLE] = ESN{ + esnTypes[String_ESN_DISABLE] = ESN{ needESN: false, } } diff --git a/security/integ/auth_hmac_md5_96.go b/security/integ/auth_hmac_md5_96.go index d868db5..7b541c5 100644 --- a/security/integ/auth_hmac_md5_96.go +++ b/security/integ/auth_hmac_md5_96.go @@ -8,39 +8,37 @@ import ( "github.com/free5gc/ike/message" ) -const string_AUTH_HMAC_MD5_96 string = "AUTH_HMAC_MD5_96" - func toString_AUTH_HMAC_MD5_96(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_AUTH_HMAC_MD5_96 + return AUTH_HMAC_MD5_96 } var ( - _ INTEGType = &AUTH_HMAC_MD5_96{} - _ INTEGKType = &AUTH_HMAC_MD5_96{} + _ INTEGType = &AuthHmacMd5_95{} + _ INTEGKType = &AuthHmacMd5_95{} ) -type AUTH_HMAC_MD5_96 struct { +type AuthHmacMd5_95 struct { keyLength int outputLength int } -func (t *AUTH_HMAC_MD5_96) TransformID() uint16 { +func (t *AuthHmacMd5_95) TransformID() uint16 { return message.AUTH_HMAC_MD5_96 } -func (t *AUTH_HMAC_MD5_96) getAttribute() (bool, uint16, uint16, []byte) { +func (t *AuthHmacMd5_95) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *AUTH_HMAC_MD5_96) GetKeyLength() int { +func (t *AuthHmacMd5_95) GetKeyLength() int { return t.keyLength } -func (t *AUTH_HMAC_MD5_96) GetOutputLength() int { +func (t *AuthHmacMd5_95) GetOutputLength() int { return t.outputLength } -func (t *AUTH_HMAC_MD5_96) Init(key []byte) hash.Hash { +func (t *AuthHmacMd5_95) Init(key []byte) hash.Hash { if len(key) == 16 { return hmac.New(md5.New, key) } else { diff --git a/security/integ/auth_hmac_sha1_96.go b/security/integ/auth_hmac_sha1_96.go index ad3a8a7..aba7041 100644 --- a/security/integ/auth_hmac_sha1_96.go +++ b/security/integ/auth_hmac_sha1_96.go @@ -8,39 +8,37 @@ import ( "github.com/free5gc/ike/message" ) -const string_AUTH_HMAC_SHA1_96 string = "AUTH_HMAC_SHA1_96" - func toString_AUTH_HMAC_SHA1_96(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_AUTH_HMAC_SHA1_96 + return AUTH_HMAC_SHA1_96 } var ( - _ INTEGType = &AUTH_HMAC_SHA1_96{} - _ INTEGKType = &AUTH_HMAC_SHA1_96{} + _ INTEGType = &AuthHmacSha1_96{} + _ INTEGKType = &AuthHmacSha1_96{} ) -type AUTH_HMAC_SHA1_96 struct { +type AuthHmacSha1_96 struct { keyLength int outputLength int } -func (t *AUTH_HMAC_SHA1_96) TransformID() uint16 { +func (t *AuthHmacSha1_96) TransformID() uint16 { return message.AUTH_HMAC_SHA1_96 } -func (t *AUTH_HMAC_SHA1_96) getAttribute() (bool, uint16, uint16, []byte) { +func (t *AuthHmacSha1_96) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *AUTH_HMAC_SHA1_96) GetKeyLength() int { +func (t *AuthHmacSha1_96) GetKeyLength() int { return t.keyLength } -func (t *AUTH_HMAC_SHA1_96) GetOutputLength() int { +func (t *AuthHmacSha1_96) GetOutputLength() int { return t.outputLength } -func (t *AUTH_HMAC_SHA1_96) Init(key []byte) hash.Hash { +func (t *AuthHmacSha1_96) Init(key []byte) hash.Hash { if len(key) == 20 { return hmac.New(sha1.New, key) } else { diff --git a/security/integ/auth_hmac_sha2_256_128.go b/security/integ/auth_hmac_sha2_256_128.go index d0b3a4d..b044fce 100644 --- a/security/integ/auth_hmac_sha2_256_128.go +++ b/security/integ/auth_hmac_sha2_256_128.go @@ -8,39 +8,37 @@ import ( "github.com/free5gc/ike/message" ) -const string_AUTH_HMAC_SHA2_256_128 string = "AUTH_HMAC_SHA2_256_128" - func toString_AUTH_HMAC_SHA2_256_128(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_AUTH_HMAC_SHA2_256_128 + return AUTH_HMAC_SHA2_256_128 } var ( - _ INTEGType = &AUTH_HMAC_SHA2_256_128{} - _ INTEGKType = &AUTH_HMAC_SHA2_256_128{} + _ INTEGType = &AuthHmacSha2_256_128{} + _ INTEGKType = &AuthHmacSha2_256_128{} ) -type AUTH_HMAC_SHA2_256_128 struct { +type AuthHmacSha2_256_128 struct { keyLength int outputLength int } -func (t *AUTH_HMAC_SHA2_256_128) TransformID() uint16 { +func (t *AuthHmacSha2_256_128) TransformID() uint16 { return message.AUTH_HMAC_SHA2_256_128 } -func (t *AUTH_HMAC_SHA2_256_128) getAttribute() (bool, uint16, uint16, []byte) { +func (t *AuthHmacSha2_256_128) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *AUTH_HMAC_SHA2_256_128) GetKeyLength() int { +func (t *AuthHmacSha2_256_128) GetKeyLength() int { return t.keyLength } -func (t *AUTH_HMAC_SHA2_256_128) GetOutputLength() int { +func (t *AuthHmacSha2_256_128) GetOutputLength() int { return t.outputLength } -func (t *AUTH_HMAC_SHA2_256_128) Init(key []byte) hash.Hash { +func (t *AuthHmacSha2_256_128) Init(key []byte) hash.Hash { if len(key) == 32 { return hmac.New(sha256.New, key) } else { diff --git a/security/integ/integ.go b/security/integ/integ.go index f80f4f8..09c1f1e 100644 --- a/security/integ/integ.go +++ b/security/integ/integ.go @@ -6,6 +6,12 @@ import ( "github.com/free5gc/ike/message" ) +const ( + AUTH_HMAC_MD5_96 string = "AUTH_HMAC_MD5_96" + AUTH_HMAC_SHA1_96 string = "AUTH_HMAC_SHA1_96" + AUTH_HMAC_SHA2_256_128 string = "AUTH_HMAC_SHA2_256_128" +) + var integString map[uint16]func(uint16, uint16, []byte) string var ( @@ -23,15 +29,15 @@ func init() { // INTEG Types integTypes = make(map[string]INTEGType) - integTypes[string_AUTH_HMAC_MD5_96] = &AUTH_HMAC_MD5_96{ + integTypes[AUTH_HMAC_MD5_96] = &AuthHmacMd5_95{ keyLength: 16, outputLength: 12, } - integTypes[string_AUTH_HMAC_SHA1_96] = &AUTH_HMAC_SHA1_96{ + integTypes[AUTH_HMAC_SHA1_96] = &AuthHmacSha1_96{ keyLength: 20, outputLength: 12, } - integTypes[string_AUTH_HMAC_SHA2_256_128] = &AUTH_HMAC_SHA2_256_128{ + integTypes[AUTH_HMAC_SHA2_256_128] = &AuthHmacSha2_256_128{ keyLength: 32, outputLength: 16, } @@ -39,15 +45,15 @@ func init() { // INTEG Kernel Types integKTypes = make(map[string]INTEGKType) - integKTypes[string_AUTH_HMAC_MD5_96] = &AUTH_HMAC_MD5_96{ + integKTypes[AUTH_HMAC_MD5_96] = &AuthHmacMd5_95{ keyLength: 16, outputLength: 12, } - integKTypes[string_AUTH_HMAC_SHA1_96] = &AUTH_HMAC_SHA1_96{ + integKTypes[AUTH_HMAC_SHA1_96] = &AuthHmacSha1_96{ keyLength: 20, outputLength: 12, } - integKTypes[string_AUTH_HMAC_SHA2_256_128] = &AUTH_HMAC_SHA2_256_128{ + integKTypes[AUTH_HMAC_SHA2_256_128] = &AuthHmacSha2_256_128{ keyLength: 32, outputLength: 16, } diff --git a/security/lib/lib.go b/security/lib/lib.go index 376c5bf..a391d0b 100644 --- a/security/lib/lib.go +++ b/security/lib/lib.go @@ -1,17 +1,31 @@ package lib import ( - "bytes" + "crypto/rand" "hash" + "math" + + "github.com/pkg/errors" ) -func PKCS7Padding(plainText []byte, blockSize int) []byte { +func PKCS7Padding(plainText []byte, blockSize int) ([]byte, error) { padding := blockSize - (len(plainText) % blockSize) if padding == 0 { padding = blockSize } - paddingText := bytes.Repeat([]byte{byte(padding)}, padding) - return append(plainText, paddingText...) + maxNum := math.MaxUint8 + paddingText := make([]byte, padding) + _, err := rand.Read(paddingText) + if err != nil { + return nil, errors.Wrapf(err, "PKCS7Padding()") + } + + for i := 0; i < padding-1; i++ { + paddingText[i] = byte(int(paddingText[i]) % (maxNum + 1)) + } + + paddingText[len(paddingText)-1] = byte(padding - 1) + return append(plainText, paddingText...), nil } func PrfPlus(prf hash.Hash, s []byte, streamLen int) []byte { diff --git a/security/prf/prf.go b/security/prf/prf.go index c52fdbc..ee70a60 100644 --- a/security/prf/prf.go +++ b/security/prf/prf.go @@ -6,6 +6,12 @@ import ( "github.com/free5gc/ike/message" ) +const ( + PRF_HMAC_MD5 string = "PRF_HMAC_MD5" + PRF_HMAC_SHA1 string = "PRF_HMAC_SHA1" + PRF_HMAC_SHA2_256 string = "PRF_HMAC_SHA2_256" +) + var ( prfString map[uint16]func(uint16, uint16, []byte) string prfTypes map[string]PRFType @@ -21,15 +27,15 @@ func init() { // PRF Types prfTypes = make(map[string]PRFType) - prfTypes[string_PRF_HMAC_MD5] = &PRF_HMAC_MD5{ + prfTypes[PRF_HMAC_MD5] = &PrfHmacMd5{ keyLength: 16, outputLength: 16, } - prfTypes[string_PRF_HMAC_SHA1] = &PRF_HMAC_SHA1{ + prfTypes[PRF_HMAC_SHA1] = &PrfHmacSha1{ keyLength: 20, outputLength: 20, } - prfTypes[string_PRF_HMAC_SHA2_256] = &PRF_HMAC_SHA2_256{ + prfTypes[PRF_HMAC_SHA2_256] = &PrfHmacSha2_256{ keyLength: 32, outputLength: 32, } diff --git a/security/prf/prf_hmac_md5.go b/security/prf/prf_hmac_md5.go index 6fab236..394944c 100644 --- a/security/prf/prf_hmac_md5.go +++ b/security/prf/prf_hmac_md5.go @@ -8,35 +8,33 @@ import ( "github.com/free5gc/ike/message" ) -const string_PRF_HMAC_MD5 string = "PRF_HMAC_MD5" - func toString_PRF_HMAC_MD5(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_PRF_HMAC_MD5 + return PRF_HMAC_MD5 } -var _ PRFType = &PRF_HMAC_MD5{} +var _ PRFType = &PrfHmacMd5{} -type PRF_HMAC_MD5 struct { +type PrfHmacMd5 struct { keyLength int outputLength int } -func (t *PRF_HMAC_MD5) TransformID() uint16 { +func (t *PrfHmacMd5) TransformID() uint16 { return message.PRF_HMAC_MD5 } -func (t *PRF_HMAC_MD5) getAttribute() (bool, uint16, uint16, []byte) { +func (t *PrfHmacMd5) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *PRF_HMAC_MD5) GetKeyLength() int { +func (t *PrfHmacMd5) GetKeyLength() int { return t.keyLength } -func (t *PRF_HMAC_MD5) GetOutputLength() int { +func (t *PrfHmacMd5) GetOutputLength() int { return t.outputLength } -func (t *PRF_HMAC_MD5) Init(key []byte) hash.Hash { +func (t *PrfHmacMd5) Init(key []byte) hash.Hash { return hmac.New(md5.New, key) } diff --git a/security/prf/prf_hmac_sha1.go b/security/prf/prf_hmac_sha1.go index ddd0198..401fa9a 100644 --- a/security/prf/prf_hmac_sha1.go +++ b/security/prf/prf_hmac_sha1.go @@ -8,35 +8,33 @@ import ( "github.com/free5gc/ike/message" ) -const string_PRF_HMAC_SHA1 string = "PRF_HMAC_SHA1" - func toString_PRF_HMAC_SHA1(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_PRF_HMAC_SHA1 + return PRF_HMAC_SHA1 } -var _ PRFType = &PRF_HMAC_SHA1{} +var _ PRFType = &PrfHmacSha1{} -type PRF_HMAC_SHA1 struct { +type PrfHmacSha1 struct { keyLength int outputLength int } -func (t *PRF_HMAC_SHA1) TransformID() uint16 { +func (t *PrfHmacSha1) TransformID() uint16 { return message.PRF_HMAC_SHA1 } -func (t *PRF_HMAC_SHA1) getAttribute() (bool, uint16, uint16, []byte) { +func (t *PrfHmacSha1) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *PRF_HMAC_SHA1) GetKeyLength() int { +func (t *PrfHmacSha1) GetKeyLength() int { return t.keyLength } -func (t *PRF_HMAC_SHA1) GetOutputLength() int { +func (t *PrfHmacSha1) GetOutputLength() int { return t.outputLength } -func (t *PRF_HMAC_SHA1) Init(key []byte) hash.Hash { +func (t *PrfHmacSha1) Init(key []byte) hash.Hash { return hmac.New(sha1.New, key) } diff --git a/security/prf/prf_hmac_sha2_256.go b/security/prf/prf_hmac_sha2_256.go index c26d2d7..caebbfc 100644 --- a/security/prf/prf_hmac_sha2_256.go +++ b/security/prf/prf_hmac_sha2_256.go @@ -8,35 +8,33 @@ import ( "github.com/free5gc/ike/message" ) -const string_PRF_HMAC_SHA2_256 string = "PRF_HMAC_SHA2_256" - func toString_PRF_HMAC_SHA2_256(attrType uint16, intValue uint16, bytesValue []byte) string { - return string_PRF_HMAC_SHA2_256 + return PRF_HMAC_SHA2_256 } -var _ PRFType = &PRF_HMAC_SHA2_256{} +var _ PRFType = &PrfHmacSha2_256{} -type PRF_HMAC_SHA2_256 struct { +type PrfHmacSha2_256 struct { keyLength int outputLength int } -func (t *PRF_HMAC_SHA2_256) TransformID() uint16 { +func (t *PrfHmacSha2_256) TransformID() uint16 { return message.PRF_HMAC_SHA2_256 } -func (t *PRF_HMAC_SHA2_256) getAttribute() (bool, uint16, uint16, []byte) { +func (t *PrfHmacSha2_256) getAttribute() (bool, uint16, uint16, []byte) { return false, 0, 0, nil } -func (t *PRF_HMAC_SHA2_256) GetKeyLength() int { +func (t *PrfHmacSha2_256) GetKeyLength() int { return t.keyLength } -func (t *PRF_HMAC_SHA2_256) GetOutputLength() int { +func (t *PrfHmacSha2_256) GetOutputLength() int { return t.outputLength } -func (t *PRF_HMAC_SHA2_256) Init(key []byte) hash.Hash { +func (t *PrfHmacSha2_256) Init(key []byte) hash.Hash { return hmac.New(sha256.New, key) }