Skip to content

Commit

Permalink
Prevent Invalid Curve Attack on 5G SUCI Feature (#20)
Browse files Browse the repository at this point in the history
* Prevent Invalid Curve Attack on 5G SUCI Feature

* add test case of detecting invalid cure attack

* fix comment

* change test case err type

---------

Co-authored-by: Roy-Hu <r74774777@gmail.com>
Co-authored-by: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw>
  • Loading branch information
3 people committed May 8, 2023
1 parent a63c83d commit 5e1479c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
18 changes: 18 additions & 0 deletions pkg/suci/suci.go
Expand Up @@ -218,6 +218,20 @@ func profileA(input, supiType, privateKey string) (string, error) {
return calcSchemeResult(decryptPlainText, supiType), nil
}

func checkOnCurve(curve elliptic.Curve, x, y *big.Int) error {
// (0, 0) is the point at infinity by convention. It's ok to operate on it,
// although IsOnCurve is documented to return false for it. See Issue 37294.
if x.Sign() == 0 && y.Sign() == 0 {
return nil
}

if !curve.IsOnCurve(x, y) {
return fmt.Errorf("crypto/elliptic: attempted operation on invalid point")
}

return nil
}

func profileB(input, supiType, privateKey string) (string, error) {
logger.SuciLog.Infoln("SuciToSupi Profile B")
s, hexDecodeErr := hex.DecodeString(input)
Expand Down Expand Up @@ -271,6 +285,10 @@ func profileB(input, supiType, privateKey string) (string, error) {
}
// fmt.Printf("xUncom: %x\nyUncom: %x\n", xUncompressed, yUncompressed)

if err := checkOnCurve(elliptic.P256(), xUncompressed, yUncompressed); err != nil {
return "", err
}

// x-coordinate is the shared key
decryptSharedKey, _ := elliptic.P256().ScalarMult(xUncompressed, yUncompressed, bHNPriv)
// fmt.Printf("deShared: %x\n", decryptSharedKey.Bytes())
Expand Down
35 changes: 25 additions & 10 deletions pkg/suci/suci_test.go
@@ -1,6 +1,9 @@
package suci

import "testing"
import (
"fmt"
"testing"
)

func TestToSupi(t *testing.T) {
suciProfiles := []SuciProfile{
Expand All @@ -17,30 +20,42 @@ func TestToSupi(t *testing.T) {
},
}
testCases := []struct {
suci string
expected string
suci string
expectedSupi string
expectedErr error
}{
{
suci: "suci-0-208-93-0-0-0-00007487",
expected: "imsi-2089300007487",
suci: "suci-0-208-93-0-0-0-00007487",
expectedSupi: "imsi-2089300007487",
expectedErr: nil,
},
{
suci: "suci-0-208-93-0-1-1-b2e92f836055a255837debf850b528997ce0201cb82a" +
"dfe4be1f587d07d8457dcb02352410cddd9e730ef3fa87",
expected: "imsi-20893001002086",
expectedSupi: "imsi-20893001002086",
expectedErr: nil,
},
{
suci: "suci-0-208-93-0-2-2-039aab8376597021e855679a9778ea0b67396e68c66d" +
"f32c0f41e9acca2da9b9d146a33fc2716ac7dae96aa30a4d",
expected: "imsi-20893001002086",
expectedSupi: "imsi-20893001002086",
expectedErr: nil,
},
{
suci: "suci-0-208-93-0-2-2-0434a66778799d52fedd9326db4b690d092e05c9ba0ace5b413da" +
"fc0a40aa28ee00a79f790fa4da6a2ece892423adb130dc1b30e270b7d0088bdd716b93894891d5221a74c810d6b9350cc067c76",
expectedSupi: "",
expectedErr: fmt.Errorf("crypto/elliptic: attempted operation on invalid point"),
},
}
for i, tc := range testCases {
supi, err := ToSupi(tc.suci, suciProfiles)
if err != nil {
t.Errorf("TC%d err: %+v\n", i, err)
} else if supi != tc.expected {
t.Errorf("TC%d fail: supi[%s], expected[%s]\n", i, supi, tc.expected)
if err.Error() != tc.expectedErr.Error() {
t.Errorf("TC%d fail: err[%s], expected[%s]\n", i, err, tc.expectedErr)
}
} else if supi != tc.expectedSupi {
t.Errorf("TC%d fail: supi[%s], expected[%s]\n", i, supi, tc.expectedSupi)
}
}
}

0 comments on commit 5e1479c

Please sign in to comment.