Skip to content
오늘을살자
Go back

DoIP에서 Security Access 뒤 NRC 0x24가 뜬다: seed/key 이후 요청 순서와 세션 문맥을 같이 봐야 한다

Edit page

Security Access를 붙이다 보면 계산 로직보다 먼저 순서에서 막히는 경우가 있다.

이때 key 알고리즘부터 의심하기 쉽다.
그런데 실제로는 seed/key 순서와 세션 문맥이 중간에 어긋난 경우가 더 자주 보인다.

오늘 메모는 DoIP에서 NRC 0x24 Request Sequence Error를 볼 때 먼저 확인할 순서다.

0x24는 순서가 틀렸다는 신호에 가깝다

0x24는 흔히 이렇게 읽는다.

요청 자체를 모르는 건 아닌데, 지금 이 상태에서 그 요청이 올 차례는 아니다.

즉 이 코드는 보통 아래 둘과 다르다.

그래서 0x24가 뜨면 계산식보다 먼저
이 요청이 같은 unlock 흐름 위에 올라가 있는지를 봐야 한다.

Security Access는 요청 두 개만 맞으면 끝나지 않는다

겉으로는 단순하다.

seed request
-> seed response
-> key request
-> unlock success

그런데 실무에서는 이 흐름 사이에 같이 유지돼야 하는 것이 더 있다.

즉 seed와 key만 연달아 보지 말고
같은 연결 세대의 같은 transaction 흐름인지를 같이 확인해야 한다.

자주 터지는 패턴 1: seed 받고 다른 문맥에서 key를 보낸다

이게 제일 흔하다.

예를 들면 이런 식이다.

SecurityAccess requestSeed
-> seed 응답 수신
-> TCP 재연결 또는 RA 재수행
-> 이전 seed로 key 전송
-> NRC 0x24

테스터 로그에는 “방금 seed 받았는데 왜 안 되지?”처럼 보이지만,
ECU 입장에서는 이전 연결 문맥의 seed일 수 있다.

DoIP에서는 특히 아래 이벤트가 끼면 순서가 무효화되기 쉽다.

이후에는 seed를 다시 받아야 하는 경우가 많다.

자주 터지는 패턴 2: seed/key 사이에 다른 요청이 끼어든다

멀티 스레드 테스터에서 많이 본다.

task A: requestSeed
task B: DID read
task A: sendKey
-> NRC 0x24

애플리케이션 입장에서는 DID read 하나쯤 괜찮아 보일 수 있다.
하지만 ECU 구현에 따라서는 Security Access를 짧은 순차 흐름으로 기대한다.

특히 아래 요청이 사이에 들어가면 더 헷갈린다.

이 경우 네트워크보다 먼저
동일 ECU 대상 요청 직렬화를 의심하는 편이 빠르다.

자주 터지는 패턴 3: requestSeed를 두 번 보내고 마지막 seed를 안 쓴다

자동 재시도 코드가 있으면 이런 실수도 나온다.

requestSeed #1
-> seed A
requestSeed #2
-> seed B
sendKey(key from seed A)
-> NRC 0x24 또는 unlock 실패

로그를 길게 보면 분명 seed는 받았는데,
실제로 key 계산에 쓴 값이 마지막 seed가 아닌 경우가 있다.

특히 아래 조건에서 잘 숨는다.

이때 0x24는 계산 오류처럼 보이기보다
요청 시퀀스 관리가 흐트러졌다는 힌트로 보는 게 낫다.

자주 터지는 패턴 4: unlock 뒤 세션이 바뀌었는데 그대로 다음 요청을 보낸다

어떤 ECU는 unlock 성공 직후에도
다음 요청이 특정 세션 위에서만 유효하다.

예를 들면:

이때 unlock 응답만 보고 곧바로 다음 서비스를 보내면
실패 코드가 0x24로 보이기도 한다.

즉 Security Access 디버깅은
key 성공 여부 하나보다 unlock 이후 세션 문맥 유지를 같이 봐야 한다.

로그를 이렇게 남기면 빨라진다

0x24는 패킷 한 줄만 보면 잘 안 풀린다.
나는 보통 아래 항목을 붙여 본다.

  1. SecurityAccess sub-function과 level
  2. seed 수신 시각과 seed 식별값 일부
  3. key 전송 시각과 그 사이에 낀 다른 요청
  4. 소켓 재연결, Routing Activation, 세션 전환 이벤트
  5. unlock 이후 첫 후속 요청의 서비스 ID

이 다섯 줄이 있으면
“알고리즘이 틀린가”보다
“같은 흐름 위에서 key를 보냈는가”가 먼저 보인다.

구현 쪽에서 무난한 패턴

실무에서는 아래처럼 묶어두는 편이 덜 꼬인다.

requestSeed
-> seed 저장
-> 같은 ECU/세션/연결 세대에서만 sendKey 허용
-> unlock 성공 전까지 다른 충돌 요청 직렬화
-> 재연결/세션 변경/reset 발생 시 seed 문맥 폐기

핵심은 seed를 단순 바이트 배열이 아니라
세션에 종속된 상태값으로 보는 것이다.

가능하면 연결 컨텍스트에 이런 값을 같이 두는 편이 좋다.

빠른 체크리스트

  1. requestSeedsendKey 사이에 재연결이나 RA 재수행이 없는지 확인
  2. 중간에 다른 UDS 요청이 끼어들지 않도록 같은 ECU 요청을 직렬화했는지 확인
  3. 자동 재시도로 seed를 두 번 받아 놓고 이전 seed로 key를 계산하지 않는지 확인
  4. unlock 이후 필요한 세션 전환 순서를 코드에 명시했는지 확인
  5. 0x24를 단순 key 계산 실패로 뭉개지 않고 시퀀스 오류로 분리 기록하는지 확인

한 줄 요약

DoIP에서 Security Access 뒤 NRC 0x24가 뜨면 key 알고리즘보다 먼저 seed/key 사이에 연결, 세션, 병렬 요청이 끼어 같은 unlock 문맥이 깨졌는지 확인하는 편이 빠르다.

추천 키워드

DoIP, UDS, Security Access, NRC, Request Sequence Error, Session Control


DevBJ | 오늘을살자, Log Today


Edit page
Share this post on:

Previous Post
lwIP에서 tcpip_thread 안에서 다시 기다리면 멈춘다: callback 안의 netconn/sockets 호출이 self-deadlock이 되는 이유
Next Post
lwIP에서 UDP 길이가 가끔 잘못 읽힌다: pbuf 체인에서는 len 말고 tot_len을 봐야 한다