【5G核心网】free5GC UE安全鉴权流程源码分析
本文分析 Free5gc UE 安全鉴权流程
1. AMF 向 AUSF 发起 Nausf_UE_Authentication 请求
Authentication
--> AuthenticationProcedure
--> SendUEAuthenticationAuthenticateRequest
func SendUEAuthenticationAuthenticateRequest(ue *amf_context.AmfUe,resynchronizationInfo *models.ResynchronizationInfo) (*models.UeAuthenticationCtx, *models.ProblemDetails, error) {configuration := Nausf_UEAuthentication.NewConfiguration()configuration.SetBasePath(ue.AusfUri)client := Nausf_UEAuthentication.NewAPIClient(configuration)amfSelf := amf_context.AMF_Self()servedGuami := amfSelf.ServedGuamiList[0]var authInfo models.AuthenticationInfoauthInfo.SupiOrSuci = ue.Suciif mnc, err := strconv.Atoi(servedGuami.PlmnId.Mnc); err != nil {return nil, nil, err} else {authInfo.ServingNetworkName = fmt.Sprintf("5G:mnc%03d.mcc%s.3gppnetwork.org", mnc, servedGuami.PlmnId.Mcc)}if resynchronizationInfo != nil {authInfo.ResynchronizationInfo = resynchronizationInfo}ueAuthenticationCtx, httpResponse, err := client.DefaultApi.UeAuthenticationsPost(context.Background(), authInfo)if err == nil {return &ueAuthenticationCtx, nil, nil} else if httpResponse != nil {if httpResponse.Status != err.Error() {return nil, nil, err}problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)return nil, &problem, nil} else {return nil, nil, openapi.ReportError("server no response")}
}
AMF 收到注册请求,如果 AMF 不存在 UE 安全上下文,则发起验证流程,AMF 向 AUSF 发起 Nausf_UEAuthentications 流程,包括 SUCI/SUPI 或者服务网络名
Resource URI: {apiRoot}/nausf-auth/v1/ue-authentications
2. AUSF 处理 Authentication 请求
HTTPUeAuthenticationsPost
--> HandleUeAuthPostRequest
--> UeAuthPostRequestProcedure
func UeAuthPostRequestProcedure(updateAuthenticationInfo models.AuthenticationInfo) (*models.UeAuthenticationCtx,string, *models.ProblemDetails) {var responseBody models.UeAuthenticationCtxvar authInfoReq models.AuthenticationInfoRequestsupiOrSuci := updateAuthenticationInfo.SupiOrSucisnName := updateAuthenticationInfo.ServingNetworkName
2.1 根据服务网络名,AUSF 决定是否 AMF 有权发送此消息
如果服务网络未被授权,则 AUSF 应使用 SERVING_NETWORK_NOT_AUTHORIZED “原因”。 但是这里比较简单,只是正则表达式匹配 5G:mnc[0-9]{3}[.]mcc[0-9]{3}[.]3gppnetwork[.]org
snName := updateAuthenticationInfo.ServingNetworkName
servingNetworkAuthorized := ausf_context.IsServingNetworkAuthorized(snName)
if !servingNetworkAuthorized {var problemDetails models.ProblemDetailsproblemDetails.Cause = "SERVING_NETWORK_NOT_AUTHORIZED"problemDetails.Status = http.StatusForbiddenlogger.UeAuthPostLog.Infoln("403 forbidden: serving network NOT AUTHORIZED")return nil, "", &problemDetails
}
logger.UeAuthPostLog.Infoln("Serving network authorized")
2.2 如果请求 body 包含 ResynchronizationInfo
if updateAuthenticationInfo.ResynchronizationInfo != nil {logger.UeAuthPostLog.Warningln("Auts: ", updateAuthenticationInfo.ResynchronizationInfo.Auts)ausfCurrentSupi := ausf_context.GetSupiFromSuciSupiMap(supiOrSuci)logger.UeAuthPostLog.Warningln(ausfCurrentSupi)ausfCurrentContext := ausf_context.GetAusfUeContext(ausfCurrentSupi)logger.UeAuthPostLog.Warningln(ausfCurrentContext.Rand)updateAuthenticationInfo.ResynchronizationInfo.Rand = ausfCurrentContext.Randlogger.UeAuthPostLog.Warningln("Rand: ", updateAuthenticationInfo.ResynchronizationInfo.Rand)authInfoReq.ResynchronizationInfo = updateAuthenticationInfo.ResynchronizationInfo
}
实例化 var authInfoReq models.AuthenticationInfoRequest,并赋值,猜测应该是向 UDM 请求的 body
type AuthenticationInfoRequest struct {SupportedFeatures string `json:"supportedFeatures,omitempty" yaml:"supportedFeatures" bson:"supportedFeatures" mapstructure:"SupportedFeatures"`ServingNetworkName string `json:"servingNetworkName" yaml:"servingNetworkName" bson:"servingNetworkName" mapstructure:"ServingNetworkName"`ResynchronizationInfo *ResynchronizationInfo `json:"resynchronizationInfo,omitempty" yaml:"resynchronizationInfo" bson:"resynchronizationInfo" mapstructure:"ResynchronizationInfo"`AusfInstanceId string `json:"ausfInstanceId" yaml:"ausfInstanceId" bson:"ausfInstanceId" mapstructure:"AusfInstanceId"`
}
2.3 AUSF 向 UDM 请求SUPI / SUCI 的身份验证信息数据
NF 服务使用者(AUSF)从 UDM 请求 SUPI / SUCI 的身份验证信息数据。 如果提供了 SUCI,则 UDM 根据 SUCI 计算 SUPI(请参阅3GPP TS 33.501 [6])。 如果选择了 5G AKA 或 EAP-AKA',则 UDM 会考虑从 NF 服务使用者(AUSF)接收到的信息以及该资源的当前表示来计算认证向量。 有关详细信息,请参见 3GPP TS 33.501 [6]。
GenerateAuthData 向 UDM 发送请求,/nudm-ueau/v1/{udId}/security-information/generate-auth-data
udmUrl := getUdmUrl(self.NrfUri)
client := createClientToUdmUeau(udmUrl)
authInfoResult, _, err := client.GenerateAuthDataApi.GenerateAuthData(context.Background(), supiOrSuci, authInfoReq)
if err != nil {logger.UeAuthPostLog.Infoln(err.Error())var problemDetails models.ProblemDetailsif authInfoResult.AuthenticationVector == nil {problemDetails.Cause = "AV_GENERATION_PROBLEM"} else {problemDetails.Cause = "UPSTREAM_SERVER_ERROR"}problemDetails.Status = http.StatusInternalServerErrorreturn nil, "", &problemDetails
}
3. UDM 处理 AUSF 的身份验证信息数据请求
/:supiOrSuci/security-information/generate-auth-data
--> HttpGenerateAuthData
--> HandleGenerateAuthDataRequest
--> GenerateAuthDataProcedure
如果提供了 SUCI,则 UDM 根据 SUCI 计算 SUPI(请参阅3GPP TS 33.501 [6])。 如果选择了 5G AKA 或 EAP-AKA',则 UDM 会考虑从 NF 服务使用者(AUSF)接收到的信息以及该资源的当前表示来计算认证向量。 有关详细信息,请参见 3GPP TS 33.501 [6]。
func GenerateAuthDataProcedure(authInfoRequest models.AuthenticationInfoRequest, supiOrSuci string) (response *models.AuthenticationInfoResult, problemDetails *models.ProblemDetails) {logger.UeauLog.Traceln("In GenerateAuthDataProcedure")response = &models.AuthenticationInfoResult{}rand.Seed(time.Now().UnixNano())supi, err := suci.ToSupi(supiOrSuci)
3.1 UDM 向 UDR 查询鉴权数据
/subscription-data/{ueId}/authentication-data/authentication-subscription, 包括 OP OPC K SQN
client := createUDMClientToUDR(supi, false)
authSubs, _, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(context.Background(), supi, nil)
if err != nil {problemDetails = &models.ProblemDetails{Status: http.StatusForbidden,Cause: authenticationRejected,Detail: err.Error(),}logger.UeauLog.Errorln("Return from UDR QueryAuthSubsData error")return nil, problemDetails
}
{ "_id" : ObjectId("5fb4baa6ea01aa3a37fd5d96"), "sequenceNumber" : "000000000022", "authenticationManagementField" : "8000", "milenage" : { "op" : { "opValue" : "c9e8763286b5b9ffbdf56e1297d0887b", "encryptionAlgorithm" : 0, "encryptionKey" : 0 } }, "opc" : { "opcValue" : "981d464c7c52eb6e5036234984ad0bcf", "encryptionAlgorithm" : 0, "encryptionKey" : 0 }, "ueId" : "imsi-2089300007487", "authenticationMethod" : "5G_AKA", "permanentKey" : { "encryptionAlgorithm" : 0, "encryptionKey" : 0, "permanentKeyValue" : "5122250214c33e723a5dd523fc145fc0" } }
3.2 AMF 硬编码 8000(Authentication Management Field)
AMF, err := hex.DecodeString("8000")
if err != nil {problemDetails = &models.ProblemDetails{Status: http.StatusForbidden,Cause: authenticationRejected,Detail: err.Error(),}logger.UeauLog.Errorln("err", err)return nil, problemDetails
}
3.3 需要重新同步的情况
// re-synchroniztion
if authInfoRequest.ResynchronizationInfo != nil {Auts, deCodeErr := hex.DecodeString(authInfoRequest.ResynchronizationInfo.Auts)if deCodeErr != nil {problemDetails = &models.ProblemDetails{Status: http.StatusForbidden,Cause: authenticationRejected,Detail: deCodeErr.Error(),}logger.UeauLog.Errorln("err", deCodeErr)return nil, problemDetails}
3.4 对 SQN 加一处理,并重新存储
// increment sqn
bigSQN := big.NewInt(0)
sqn, err = hex.DecodeString(sqnStr)
if err != nil {problemDetails = &models.ProblemDetails{Status: http.StatusForbidden,Cause: authenticationRejected,Detail: err.Error(),}logger.UeauLog.Errorln("err", err)return nil, problemDetails
}bigSQN.SetString(sqnStr, 16)bigInc := big.NewInt(1)
bigSQN = bigInc.Add(bigSQN, bigInc)SQNheStr := fmt.Sprintf("%x", bigSQN)
SQNheStr = strictHex(SQNheStr, 12)
patchItemArray := []models.PatchItem{{Op: models.PatchOperation_REPLACE,Path: "/sequenceNumber",Value: SQNheStr,},
}
- MAC = f1K(SQN || RAND || AMF)
- XRES = f2K (RAND)
- CK = f3K (RAND)
- IK = f4K (RAND)
- AK = f5K (RAND)
- AUTN = SQN Å AK || AMF || MAC
// Generate macA, macS
err = milenage.F1(opc, k, RAND, sqn, AMF, macA, macS)
if err != nil {logger.UeauLog.Errorln("milenage F1 err ", err)
}
f1 函数生成 macA 和 macS
* milenage_f1 - Milenage f1 and f1* algorithms * @opc: OPc = 128-bit value derived from OP and K * @k: K = 128-bit subscriber key * @_rand: RAND = 128-bit random challenge * @sqn: SQN = 48-bit sequence number * @amf: AMF = 16-bit authentication management field * @mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL * @mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL
3.5 生成 AUTN
// Generate RES, CK, IK, AK, AKstar
// RES == XRES (expected RES) for server
err = milenage.F2345(opc, k, RAND, RES, CK, IK, AK, AKstar)
if err != nil {logger.UeauLog.Errorln("milenage F2345 err ", err)
}
// fmt.Printf("milenage RES = %s\n", hex.EncodeToString(RES))// Generate AUTN
// fmt.Printf("SQN=%x\nAK =%x\n", SQN, AK)
// fmt.Printf("AMF=%x, macA=%x\n", AMF, macA)
SQNxorAK := make([]byte, 6)
for i := 0; i < len(sqn); i++ {SQNxorAK[i] = sqn[i] ^ AK[i]
}
// fmt.Printf("SQN xor AK = %x\n", SQNxorAK)
AUTN := append(append(SQNxorAK, AMF...), macA...)
fmt.Printf("AUTN = %x\n", AUTN)
4. AUSF 向 AMF response ue-authentications
4.1 AUSF 根据 XRES* 推导出 HXRES*
locationURI := self.Url + "/nausf-auth/v1/ue-authentications/" + supiOrSuci
putLink := locationURI
if authInfoResult.AuthType == models.AuthType__5_G_AKA {logger.UeAuthPostLog.Infoln("Use 5G AKA auth method")putLink += "/5g-aka-confirmation"// Derive HXRES* from XRES*concat := authInfoResult.AuthenticationVector.Rand + authInfoResult.AuthenticationVector.XresStarvar hxresStarBytes []byteif bytes, err := hex.DecodeString(concat); err != nil {logger.Auth5gAkaComfirmLog.Warnf("decode error: %+v", err)} else {hxresStarBytes = bytes}hxresStarAll := sha256.Sum256(hxresStarBytes)hxresStar := hex.EncodeToString(hxresStarAll[16:]) // last 128 bitslogger.Auth5gAkaComfirmLog.Infof("XresStar = %x\n", authInfoResult.AuthenticationVector.XresStar)
4.2 AUSF 根据 Kausf 推导出 Kseaf
// Derive Kseaf from Kausf
Kausf := authInfoResult.AuthenticationVector.Kausf
var KausfDecode []byte
if ausfDecode, err := hex.DecodeString(Kausf); err != nil {logger.Auth5gAkaComfirmLog.Warnf("AUSF decode failed: %+v", err)
} else {KausfDecode = ausfDecode
}
P0 := []byte(snName)
Kseaf := UeauCommon.GetKDFValue(KausfDecode, UeauCommon.FC_FOR_KSEAF_DERIVATION, P0, UeauCommon.KDFLen(P0))
ausfUeContext.XresStar = authInfoResult.AuthenticationVector.XresStar
ausfUeContext.Kausf = Kausf
ausfUeContext.Kseaf = hex.EncodeToString(Kseaf)
ausfUeContext.Rand = authInfoResult.AuthenticationVector.Rand
AUSF 存储上下文,只给 AMF 返回 Rand Autn HxresStar
5. AMF 向 UE 发送 Authentication Request
Gmm 消息类型为 MsgTypeAuthenticationRequest,包裹的 NGAP 消息为 DownlinkNASTransport
6. UE 向 AMF 发送 Authentication response
- 接收到 RAND 和 AUTN, USIM 首先计算匿名密钥 AK = f5K (RAND),以及检索 SQN = SQN = (SQN Å AK) Å AK
- USIM 计算 f1K (SQN || RAND || AMF),比较 MAC 和 在 AUTN 的 MAC,如果不相同,UE 将验证失败消息发送回 VLR / SGSN,并说明原因,然后用户放弃该过程。
- 接下来,USIM 验证接收到的序列号 SQN 在正确范围内。
- 如果 USIM 认为序列号不在正确的范围内,则会将同步失败(包括适当的参数)发送回VLR / SGSN,并放弃该过程。
6.1 UE 向 AMF 发送 Authentication response 同步失败
6.1.1 AMF 处理 Authentication request Synch failure
func HandleAuthenticationFailure(ue *context.AmfUe, anType models.AccessType,authenticationFailure *nasMessage.AuthenticationFailure) error {logger.GmmLog.Info("[AMF] Handle Authentication Failure")util.StopT3560(ue)
可以看到处理的失败原因包括:
- Cause5GMMMACFailure
- Cause5GMMNon5GAuthenticationUnacceptable
- Cause5GMMngKSIAlreadyInUse
- Cause5GMMSynchFailure
对于 Synch failure 的情况处理,超过两次则 reject 处理
case nasMessage.Cause5GMMSynchFailure: // TS 24.501 5.4.1.3.7 case flogger.GmmLog.Warn("Authentication Failure 5GMM Cause: Synch Failure")ue.AuthFailureCauseSynchFailureTimes++if ue.AuthFailureCauseSynchFailureTimes >= 2 {logger.GmmLog.Warnf("2 consecutive Synch Failure, terminate authentication procedure")gmm_message.SendAuthenticationReject(ue.RanUe[anType], "")return GmmFSM.SendEvent(ue.State[anType], AuthFailEvent, fsm.ArgsType{ArgAmfUe: ue, ArgAccessType: anType})}
6.1.1.1 SendUEAuthenticationAuthenticateRequest 重新向 AUSF 发送鉴权请求
则进入第 2 章节进行处理, 这次包含 resynchronizationInfo 的处理
【5G核心网】free5GC UE安全鉴权流程源码分析相关推荐
- 【5G核心网】 free5gc Handover procedures切换流程源码分析
主要触发过程如下: 1) UE 已经在 5G 注册并建立一个 PDU 会话正在上网,并且通过源 gNB 接入到 5GC 2) UE 发生位置变换,离开源 gNB 服务区,即将进入新 gNB 服 ...
- 5G注册流程分级详解(鉴权)Step9
*** 欢迎转发,转发请注明出处 . 相关更新会在公众号公布更新,敬请关注.公众号:5G通信大家学 *** 目录 9. Authentication/Security流程. 0)准备知识 1) ...
- 核心网upf作用_高性能5G核心网,动力从何而来? 核心网,是整个通信网络的大脑,是不可或缺的重要组成部分。 网络的管理控制、鉴权认证等关键功能,主要由核心网负责。核心网的... - 雪球...
来源:雪球App,作者: 鲜枣课堂,(https://xueqiu.com/7282046183/152278945) 核心网,是整个通信网络的大脑,是不可或缺的重要组成部分. 网络的管理控制.鉴权认 ...
- Go实现的5G核心网开源项目free5gc源码分析系列 | Gopher Daily (2021.01.08) ʕ◔ϖ◔ʔ
每日一谚:"Abstractions should be discovered, not created." Go技术新闻 Go实现的5G核心网开源项目free5gc源码分析系列 ...
- 5G 核心网 UE Requested PDU Session Establishment 信令流程
I am back !!! 本系列博客将陆续更新至 3GPP TS 23.502 V15.11.0 (2020-09) 版本 首先放上 23501 中的 5G 系统架构图 : 5G 核心网采用的是S ...
- 【5G架构】5G 核心网架构概述
博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发. 在5G早期负责终端数据业务层.核心网相关的开发工作,目前牵头6G ...
- 5G核心网SBA架构
作者:柒号华仔 个人主页:欢迎访问我的主页 个人信条:星光不问赶路人,岁月不负有心人. 个人方向:专注于4G/5G领域,同时兼顾其他网络协议,编解码协议,C/C++,linux等,感兴趣的小伙伴可以关 ...
- 5G核心网之SBA架构(面向服务)
前言 随着技术演进和发展,云原生提出的"微服务"概念得到了大家的认可,微服务概念指将原本具有多个功能的集合体分拆为多个具有独立功能的个体,每个个体都具有自己的微服务.5GC将微服务 ...
- 5G核心网与核心网演进
目录 1.网络整体架构 2.NFV与5G网络功能(NF) 2.1.5G定义的网络功能(NF): 2.2.控制面与用户面分离(CUPS) 3.接口定义 3.1.基于参考点的接口 3.2.SBI:基于服务 ...
- 全新的架构——5G核心网解析
*******更多精彩5G内容请打开链接https://edu.csdn.net/course/detail/31182 5G网络面向万物互联.致力于打造智能社会,各种可预见及不可预见的业务将层出不穷 ...
最新文章
- 背包系列 hdu3449 有依赖背包
- Spotlight on oracle 使用
- python扫描内网banner信息
- java按行读取byte_【util】MappedByteBuffer按行读取的方案
- Zuul路由的strip-prefix与order
- RHEL6 cryptsetup 磁盘分区加密实验
- Duplicate Observed Data(复制“被监视数据”)
- 北京西格玛大厦微软社区精英 Visual Studio 2010 技术交流会记录
- JS+dom简单运动实现
- 超级硬盘数据恢复软件 4.6.5.0注冊码破解版
- Java面试宝典 Beta5.0版 (2018年最新公测版)
- 兰勃特等角圆锥(Lambert Conformal Conic)投影正反变换
- 应用 1:千帆竞发 ——分布式锁
- 嵌入式面试常见问题(三)
- 【学习笔记--FMCW基础知识】
- Mysql性能优化教程
- 附加作业:个人作业——案例分析
- vc文件拖曳(控件)
- 为右键新建菜单添加自定义后缀(.html, .css, .js, .py)项
- MM32F103芯片J-Link调试无法读不到芯片 ID 号