static AJ_Status KeyGen(const char* peerName, uint8_t role, const char* nonce1, const char* nonce2, uint8_t* outBuf, uint32_t len) { AJ_Status status; const uint8_t* data[4]; uint8_t lens[4]; const AJ_GUID* peerGuid = AJ_GUID_Find(peerName); AJ_PeerCred cred; status = AJ_GetRemoteCredential(peerGuid, &cred); if (AJ_OK != status) { return AJ_ERR_NO_MATCH; } data[0] = cred.secret; lens[0] = (uint32_t)sizeof(cred.secret); data[1] = (uint8_t*)nonce1; lens[1] = (uint32_t)strlen(nonce1); data[2] = (uint8_t*)nonce2; lens[2] = (uint32_t)strlen(nonce2); data[3] = (uint8_t*)"session key"; lens[3] = 11; /* * We use the outBuf to store both the key and verifier string. * Check that there is enough space to do so. */ if (len < (AES_KEY_LEN + VERIFIER_LEN)) { return AJ_ERR_RESOURCES; } status = AJ_Crypto_PRF(data, lens, ArraySize(data), outBuf, AES_KEY_LEN + VERIFIER_LEN); /* * Store the session key and compose the verifier string. */ if (status == AJ_OK) { status = AJ_SetSessionKey(peerName, outBuf, role); } if (status == AJ_OK) { memmove(outBuf, outBuf + AES_KEY_LEN, VERIFIER_LEN); status = AJ_RawToHex(outBuf, VERIFIER_LEN, (char*)outBuf, len); } return status; }
int AJ_Main(void) { AJ_Status status = AJ_OK; size_t i; char out[128]; for (i = 0; i < ArraySize(testVector); i++) { uint8_t key[16]; uint8_t msg[64]; uint8_t nonce[16]; uint32_t nlen = (uint32_t)strlen(testVector[i].nonce) / 2; uint32_t mlen = (uint32_t)strlen(testVector[i].input) / 2; AJ_HexToRaw(testVector[i].key, 0, key, sizeof(key)); AJ_HexToRaw(testVector[i].nonce, 0, nonce, nlen); AJ_HexToRaw(testVector[i].input, 0, msg, mlen); status = AJ_Encrypt_CCM(key, msg, mlen, testVector[i].hdrLen, testVector[i].authLen, nonce, nlen); if (status != AJ_OK) { AJ_Printf("Encryption failed (%d) for test #%zu\n", status, i); goto ErrorExit; } AJ_RawToHex(msg, mlen + testVector[i].authLen, out, sizeof(out), FALSE); if (strcmp(out, testVector[i].output) != 0) { AJ_Printf("Encrypt verification failure for test #%zu\n%s\n", i, out); goto ErrorExit; } /* * Verify decryption. */ status = AJ_Decrypt_CCM(key, msg, mlen, testVector[i].hdrLen, testVector[i].authLen, nonce, nlen); if (status != AJ_OK) { AJ_Printf("Authentication failure (%d) for test #%zu\n", status, i); goto ErrorExit; } AJ_RawToHex(msg, mlen, out, sizeof(out), FALSE); if (strcmp(out, testVector[i].input) != 0) { AJ_Printf("Decrypt verification failure for test #%zu\n%s\n", i, out); goto ErrorExit; } AJ_Printf("Passed and verified test #%zu\n", i); } AJ_Printf("AES CCM unit test PASSED\n"); { static const char expect[] = "F19787716404918CA20F174CFF2E165F21B17A70C472480AE91891B5BB8DD261CBD4273612D41BC6"; const char secret[] = "1234ABCDE"; const char seed[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234"; uint8_t key[40]; const char* inputs[3]; uint8_t length[3]; inputs[0] = secret; length[0] = (uint8_t)strlen(secret); inputs[1] = seed; length[1] = (uint8_t)strlen(seed); inputs[2] = "prf test"; length[2] = 8; status = AJ_Crypto_PRF((const uint8_t**)inputs, length, ArraySize(inputs), key, sizeof(key)); if (status != AJ_OK) { AJ_Printf("AJ_Crypto_PRF %d\n", status); goto ErrorExit; } AJ_RawToHex(key, sizeof(key), out, sizeof(out), FALSE); if (strcmp(out, expect) != 0) { AJ_Printf("AJ_Crypto_PRF failed: %d\n", status); goto ErrorExit; } AJ_Printf("AJ_Crypto_PRF test PASSED: %d\n", status); } return 0; ErrorExit: AJ_Printf("AES CCM unit test FAILED\n"); return 1; }