pev_cm_set_key.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /*====================================================================*
  2. Copyright (c) 2013,2021 Qualcomm Technologies, Inc.
  3. All Rights Reserved.
  4. Confidential and Proprietary - Qualcomm Technologies, Inc.
  5. ******************************************************************
  6. 2013 Qualcomm Atheros, Inc.
  7. *--------------------------------------------------------------------*/
  8. /*====================================================================*
  9. *
  10. * signed pev_cm_set_key (struct session * session, struct channel * channel, struct message * message);
  11. *
  12. * slac.h
  13. *
  14. * PEV-HLE sets the NMK and NID on PEV-PLC using CM_SET_KEY.REQ;
  15. * the NMK and NID must match those provided by EVSE-HLE using
  16. * CM_SLAC_MATCH.CNF;
  17. *
  18. * Contributor(s):
  19. * Charles Maier <cmaier@qca.qualcomm.com>
  20. *
  21. *--------------------------------------------------------------------*/
  22. #ifndef PEV_CM_SET_KEY_SOURCE
  23. #define PEV_CM_SET_KEY_SOURCE
  24. #include <string.h>
  25. #include "../ether/channel.h"
  26. #include "../tools/memory.h"
  27. #include "../tools/error.h"
  28. #include "../tools/flags.h"
  29. #include "../mme/qualcomm.h"
  30. #include "../mme/homeplug.h"
  31. #include "../slac/slac.h"
  32. #include "../plc/plc.h"
  33. signed pev_cm_set_key (struct session * session, struct channel * channel, struct message * message)
  34. {
  35. #ifndef __GNUC__
  36. #pragma pack(push,1)
  37. #endif
  38. struct __packed cm_set_key_request
  39. {
  40. struct ethernet_hdr ethernet;
  41. struct homeplug_fmi homeplug;
  42. uint8_t KEYTYPE;
  43. uint32_t MYNONCE;
  44. uint32_t YOURNONCE;
  45. uint8_t PID;
  46. uint16_t PRN;
  47. uint8_t PMN;
  48. uint8_t CCOCAP;
  49. uint8_t NID [SLAC_NID_LEN];
  50. uint8_t NEWEKS;
  51. uint8_t NEWKEY [SLAC_NMK_LEN];
  52. uint8_t RSVD [3];
  53. }
  54. * request = (struct cm_set_key_request *) (message);
  55. struct __packed cm_set_key_confirm
  56. {
  57. struct ethernet_hdr ethernet;
  58. struct homeplug_fmi homeplug;
  59. uint8_t RESULT;
  60. uint32_t MYNONCE;
  61. uint32_t YOURNONCE;
  62. uint8_t PID;
  63. uint16_t PRN;
  64. uint8_t PMN;
  65. uint8_t CCOCAP;
  66. uint8_t RSVD [27];
  67. }
  68. * confirm = (struct cm_set_key_confirm *) (message);
  69. #ifndef __GNUC__
  70. #pragma pack (pop)
  71. #endif
  72. memset (message, 0, sizeof (* message));
  73. debug (0, __func__, "--> CM_SET_KEY.REQ");
  74. EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type);
  75. HomePlugHeader1 (& request->homeplug, HOMEPLUG_MMV, (CM_SET_KEY | MMTYPE_REQ));
  76. request->KEYTYPE = SLAC_CM_SETKEY_KEYTYPE;
  77. memset (& request->MYNONCE, 0xAA, sizeof (request->MYNONCE));
  78. memset (& request->YOURNONCE, 0x00, sizeof (request->YOURNONCE));
  79. request->PID = SLAC_CM_SETKEY_PID;
  80. request->PRN = HTOLE16 (SLAC_CM_SETKEY_PRN);
  81. request->PMN = SLAC_CM_SETKEY_PMN;
  82. request->CCOCAP = SLAC_CM_SETKEY_CCO;
  83. memcpy (request->NID, session->NID, sizeof (request->NID));
  84. request->NEWEKS = SLAC_CM_SETKEY_EKS;
  85. memcpy (request->NEWKEY, session->NMK, sizeof (request->NEWKEY));
  86. #if SLAC_DEBUG
  87. if (_anyset (session->flags, SLAC_VERBOSE))
  88. {
  89. char string [1024];
  90. debug (0, __func__, "CM_SET_KEY.KEYTYPE %d", request->KEYTYPE);
  91. debug (0, __func__, "CM_SET_KEY.MYNONCE %s", hexstring (string, sizeof (string), & request->MYNONCE, sizeof (request->MYNONCE)));
  92. debug (0, __func__, "CM_SET_KEY.YOURNONCE %s", hexstring (string, sizeof (string), & request->YOURNONCE, sizeof (request->MYNONCE)));
  93. debug (0, __func__, "CM_SET_KEY.PID %d", request->PID);
  94. debug (0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (request->PRN));
  95. debug (0, __func__, "CM_SET_KEY.PMN %d", request->PMN);
  96. debug (0, __func__, "CM_SET_KEY.CCoCAP %d", request->CCOCAP);
  97. debug (0, __func__, "CM_SET_KEY.NID %s", HEXSTRING (string, request->NID));
  98. debug (0, __func__, "CM_SET_KEY.NEWEKS %d", request->NEWEKS);
  99. debug (0, __func__, "CM_SET_KEY.NEWKEY %s", HEXSTRING (string, request->NEWKEY));
  100. }
  101. #endif
  102. if (sendpacket (channel, request, sizeof (* request)) <= 0)
  103. {
  104. return (debug (1, __func__, CHANNEL_CANTSEND));
  105. }
  106. while (readpacket (channel, confirm, sizeof (* confirm)) > 0)
  107. {
  108. if (ntohs (confirm->ethernet.MTYPE) != ETH_P_HPAV)
  109. {
  110. debug (session->exit, __func__, "Ignore MTYPE 0x%04X", htons (confirm->ethernet.MTYPE));
  111. continue;
  112. }
  113. if (confirm->homeplug.MMV != HOMEPLUG_MMV)
  114. {
  115. debug (session->exit, __func__, "Ignore MMV 0x%02X", confirm->homeplug.MMV);
  116. continue;
  117. }
  118. if (LE32TOH (confirm->homeplug.MMTYPE) != (CM_SET_KEY | MMTYPE_CNF))
  119. {
  120. debug (session->exit, __func__, "Ignore MMTYPE 0x%04X", LE32TOH (confirm->homeplug.MMTYPE));
  121. continue;
  122. }
  123. debug (0, __func__, "<-- CM_SET_KEY.CNF");
  124. if (! confirm->RESULT)
  125. {
  126. return (debug (session->exit, __func__, "Can't set keys"));
  127. }
  128. #if SLAC_DEBUG
  129. if (_anyset (session->flags, SLAC_VERBOSE))
  130. {
  131. char string [1024];
  132. debug (0, __func__, "CM_SET_KEY.RESULT %d", confirm->RESULT);
  133. debug (0, __func__, "CM_SET_KEY.MYNONCE %s", hexstring (string, sizeof (string), & confirm->MYNONCE, sizeof (confirm->MYNONCE)));
  134. debug (0, __func__, "CM_SET_KEY.YOURNONCE %s", hexstring (string, sizeof (string), & confirm->YOURNONCE, sizeof (confirm->MYNONCE)));
  135. debug (0, __func__, "CM_SET_KEY.PID %d", confirm->PID);
  136. debug (0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (confirm->PRN));
  137. debug (0, __func__, "CM_SET_KEY.PMN %d", confirm->PMN);
  138. debug (0, __func__, "CM_SET_KEY.CCoCAP %d", confirm->CCOCAP);
  139. }
  140. #endif
  141. return (0);
  142. }
  143. return (debug (session->exit, __func__, "<-- CM_SET_KEY.CNF ?"));
  144. }
  145. signed pev_cm_set_key_req(struct session* session, struct channel* channel, struct message* message)
  146. {
  147. #ifndef __GNUC__
  148. #pragma pack(push,1)
  149. #endif
  150. struct __packed cm_set_key_request
  151. {
  152. struct ethernet_hdr ethernet;
  153. struct homeplug_fmi homeplug;
  154. uint8_t KEYTYPE;
  155. uint32_t MYNONCE;
  156. uint32_t YOURNONCE;
  157. uint8_t PID;
  158. uint16_t PRN;
  159. uint8_t PMN;
  160. uint8_t CCOCAP;
  161. uint8_t NID[SLAC_NID_LEN];
  162. uint8_t NEWEKS;
  163. uint8_t NEWKEY[SLAC_NMK_LEN];
  164. uint8_t RSVD[3];
  165. }
  166. *request = (struct cm_set_key_request*)(message);
  167. #ifndef __GNUC__
  168. #pragma pack (pop)
  169. #endif
  170. memset(message, 0, sizeof(*message));
  171. debug(0, __func__, "--> CM_SET_KEY.REQ");
  172. EthernetHeader(&request->ethernet, channel->peer, channel->host, channel->type);
  173. HomePlugHeader1(&request->homeplug, HOMEPLUG_MMV, (CM_SET_KEY | MMTYPE_REQ));
  174. request->KEYTYPE = SLAC_CM_SETKEY_KEYTYPE;
  175. memset(&request->MYNONCE, 0xAA, sizeof(request->MYNONCE));
  176. memset(&request->YOURNONCE, 0x00, sizeof(request->YOURNONCE));
  177. request->PID = SLAC_CM_SETKEY_PID;
  178. request->PRN = HTOLE16(SLAC_CM_SETKEY_PRN);
  179. request->PMN = SLAC_CM_SETKEY_PMN;
  180. request->CCOCAP = SLAC_CM_SETKEY_CCO;
  181. memcpy(request->NID, session->NID, sizeof(request->NID));
  182. request->NEWEKS = SLAC_CM_SETKEY_EKS;
  183. memcpy(request->NEWKEY, session->NMK, sizeof(request->NEWKEY));
  184. #if SLAC_DEBUG
  185. if (_anyset(session->flags, SLAC_VERBOSE))
  186. {
  187. char string[1024];
  188. debug(0, __func__, "CM_SET_KEY.KEYTYPE %d", request->KEYTYPE);
  189. debug(0, __func__, "CM_SET_KEY.MYNONCE %s", hexstring(string, sizeof(string), &request->MYNONCE, sizeof(request->MYNONCE)));
  190. debug(0, __func__, "CM_SET_KEY.YOURNONCE %s", hexstring(string, sizeof(string), &request->YOURNONCE, sizeof(request->MYNONCE)));
  191. debug(0, __func__, "CM_SET_KEY.PID %d", request->PID);
  192. debug(0, __func__, "CM_SET_KEY.PRN %d", LE32TOH(request->PRN));
  193. debug(0, __func__, "CM_SET_KEY.PMN %d", request->PMN);
  194. debug(0, __func__, "CM_SET_KEY.CCoCAP %d", request->CCOCAP);
  195. debug(0, __func__, "CM_SET_KEY.NID %s", HEXSTRING(string, request->NID));
  196. debug(0, __func__, "CM_SET_KEY.NEWEKS %d", request->NEWEKS);
  197. debug(0, __func__, "CM_SET_KEY.NEWKEY %s", HEXSTRING(string, request->NEWKEY));
  198. }
  199. #endif
  200. if (sendpacket(channel, request, sizeof(*request)) <= 0)
  201. {
  202. return (debug(1, __func__, CHANNEL_CANTSEND));
  203. }
  204. return 0;
  205. }
  206. signed pev_cm_set_key_cnf(struct session* session, struct channel* channel, struct message* message)
  207. {
  208. #ifndef __GNUC__
  209. #pragma pack(push,1)
  210. #endif
  211. struct __packed cm_set_key_confirm
  212. {
  213. struct ethernet_hdr ethernet;
  214. struct homeplug_fmi homeplug;
  215. uint8_t RESULT;
  216. uint32_t MYNONCE;
  217. uint32_t YOURNONCE;
  218. uint8_t PID;
  219. uint16_t PRN;
  220. uint8_t PMN;
  221. uint8_t CCOCAP;
  222. uint8_t RSVD[27];
  223. }
  224. *confirm = (struct cm_set_key_confirm*)(message);
  225. #ifndef __GNUC__
  226. #pragma pack (pop)
  227. #endif
  228. debug(0, __func__, "<-- CM_SET_KEY.CNF");
  229. if (!confirm->RESULT)
  230. {
  231. return (debug(session->exit, __func__, "Can't set keys"));
  232. }
  233. #if SLAC_DEBUG
  234. if (_anyset(session->flags, SLAC_VERBOSE))
  235. {
  236. char string[1024];
  237. debug(0, __func__, "CM_SET_KEY.RESULT %d", confirm->RESULT);
  238. debug(0, __func__, "CM_SET_KEY.MYNOUNCE %s", hexstring(string, sizeof(string), &confirm->MYNONCE, sizeof(confirm->MYNONCE)));
  239. debug(0, __func__, "CM_SET_KEY.YOURNOUNCE %s", hexstring(string, sizeof(string), &confirm->YOURNONCE, sizeof(confirm->MYNONCE)));
  240. debug(0, __func__, "CM_SET_KEY.PID %d", confirm->PID);
  241. debug(0, __func__, "CM_SET_KEY.PRN %d", LE32TOH(confirm->PRN));
  242. debug(0, __func__, "CM_SET_KEY.PMN %d", confirm->PMN);
  243. debug(0, __func__, "CM_SET_KEY.CCoCAP %d", confirm->CCOCAP);
  244. }
  245. #endif
  246. return (0);
  247. }
  248. signed pev_cm_get_key_req(struct plc* plc, void* NID)
  249. {
  250. struct channel* channel = (struct channel*)(plc->channel);
  251. struct message* message = (struct message*)(plc->message);
  252. #ifndef __GNUC__
  253. #pragma pack(push,1)
  254. #endif
  255. struct __packed cm_get_key_request
  256. {
  257. struct ethernet_hdr ethernet;
  258. struct homeplug_fmi homeplug;
  259. uint8_t REQTYPE;
  260. uint8_t KEYTYPE;
  261. uint8_t NID[SLAC_NID_LEN];
  262. uint32_t MYNONCE;
  263. uint8_t PID;
  264. uint16_t PRN;
  265. uint8_t PMN;
  266. uint8_t HASHKEY[384];
  267. }
  268. *request = (struct cm_get_key_request*)(message);
  269. #ifndef __GNUC__
  270. #pragma pack (pop)
  271. #endif
  272. memset(message, 0, sizeof(*message));
  273. debug(0, __func__, "--> CM_GET_KEY.REQ");
  274. EthernetHeader(&request->ethernet, channel->peer, channel->host, channel->type);
  275. HomePlugHeader1(&request->homeplug, HOMEPLUG_MMV, (CM_GET_KEY | MMTYPE_REQ));
  276. request->REQTYPE = 0x00; //0x00 - Direct
  277. request->KEYTYPE = SLAC_CM_SETKEY_KEYTYPE; // keytype is 0x01 for NMK
  278. memcpy(request->NID, (uint8_t*)NID, sizeof(request->NID));
  279. memset(&request->MYNONCE, 0xAA, sizeof(request->MYNONCE));
  280. request->PID = SLAC_CM_SETKEY_PID;
  281. request->PRN = HTOLE16(SLAC_CM_SETKEY_PRN);
  282. request->PMN = SLAC_CM_SETKEY_PMN;
  283. if (sendpacket(channel, request, sizeof(*request)) <= 0)
  284. {
  285. return (debug(1, __func__, CHANNEL_CANTSEND));
  286. }
  287. return 0;
  288. }
  289. signed process_pev_cm_get_key_cnf(struct plc* plc, uint8_t* NMK, uint8_t* NID)
  290. {
  291. struct message* message = (struct message*)(plc->message);
  292. #ifndef __GNUC__
  293. #pragma pack(push,1)
  294. #endif
  295. struct __packed cm_get_key_confirm
  296. {
  297. struct ethernet_hdr ethernet;
  298. struct homeplug_fmi homeplug;
  299. uint8_t RESULT;
  300. uint8_t KEYTYPE;
  301. uint32_t MYNONCE;
  302. uint32_t YOURNONCE;
  303. uint8_t NID[SLAC_NID_LEN];
  304. uint8_t EKS;
  305. uint8_t PID;
  306. uint16_t PRN;
  307. uint8_t PMN;
  308. uint8_t NMK[SLAC_NMK_LEN];
  309. }
  310. *confirm = (struct cm_get_key_confirm*)(message);
  311. #ifndef __GNUC__
  312. #pragma pack (pop)
  313. #endif
  314. debug(0, __func__, "<-- CM_GET_KEY.CNF");
  315. if (!confirm->RESULT)
  316. {
  317. return (debug(1, __func__, "Can't get keys"));
  318. }
  319. if(!memcmp(confirm->NID, NID, SLAC_NID_LEN))
  320. {
  321. return (debug(1, __func__, "NID not matching"));
  322. }
  323. if((confirm->KEYTYPE != SLAC_CM_SETKEY_KEYTYPE) || (confirm->EKS != SLAC_CM_SETKEY_EKS))
  324. {
  325. printf("key type %0x , eks %0x", confirm->KEYTYPE, confirm->EKS);
  326. return (debug(1, __func__, "keytype or eks don't match"));
  327. }
  328. memcpy(confirm->NMK, NMK, SLAC_NMK_LEN);
  329. return 0;
  330. }
  331. #endif