Tool/software:
Hello,
I am working on porting a codebase using SDK 3.40.00.02 and IAR 8.32.2 running on the CC2642R1 to simplelink sdk 7.41.00.17 and IAR 9.40.2 running on the CC1354P10. In the previous codebase I was able to carry out ECDSA signature verification without issues. However with this new codebase I notice that ECDSA_verify fails for one of my signature verification operations if a BLE connection is active, but works fine if the device is not in an active connection (even if the exact same public key, message, and signature is used). In the case where the operation fails, ECDSA_verify returns -1, which i'm assuming is the error code returned if the signature was found to be invalid. In SysConfig I have tried using both a single instance of the ECDSA module as well as 2 instances (in case the BLE stack was using the first one). But I run into the same issue in both cases. In summary, my questions are:
Please advise.
Thanks,
Keron
Hi Keron,
thank you for the detailed description. Since you are porting from an old SDK and to another device there is a lot of changes to be considered.
First, I would like to mention that we released already a newer SDK 8.30: https://www.ti.com/tool/download/SIMPLELINK-LOWPOWER-F2-SDK/8.30.00.121
Now let's dig into your questions:
1. What could be causing ECDSA_verify() to return bad status when a connection is active but return success otherwise, for the same key, message, and signature?
- Could you please clarify for me: Do you mean by connection is active that the BLE stack is running and there is no device connected or that the BLE stack is not running?
2. Do I need to include ECDSACC26X4_s.c, ECDSACC26X2.c or any other stack file for successful operation of the ECDSA driver? I have tried with and without ECDSACC26X2.c included in my project, but I get the same results either way. When I attempt to include ECDSACC26X4_s.c in the project, I get the compilation error seen in the following screenshot:
- When you add an ECDSA instance in SysConfig it is automatically including the needed source files.
- How did you add and initialize the ECDSA instance?
3. Could you explain me how you ported the projects? Did you start from a CC1354P10 example project and added your functionality?
Kind regards,
Theo
Hi Theo,
Thanks for looking into this issue. Also thanks for the heads up about the updated SDK. I tried looking at the change log referenced at that link but it leads to a 404 error. Anywhere else I can look to see the SDK differences?
Please see my response to your questions below:
1. Could you please clarify for me: Do you mean by connection is active that the BLE stack is running and there is no device connected or that the BLE stack is not running?
- I should have mentioned that our codebase is based off of the simple_central example project, so the BLE stack task is running for all of my use cases. When I say that ECDSA fails when a connection is active, I'm referring to the BLE stack task running and my device being connected to another peer. My device is set up as a simple_central and the peer device is a peripheral. When the two devices are in an active BLE connection, ECDSA verification fails with a status of -1 for one of my verification operations. However, if the two devices are not in an active BLE connection, that same ECDSA verification is successful for the same key, message, and signature.
2. How did you add and initialize the ECDSA instance?
- In SysConfig I have a couple of ECDSA instances I've defined with all default settings (i.e. CONFIG_ECDSA_0 and CONFIG_ECDSA_1). Then in code, I call ECDSA_init() after BIOS_start() has kicked off the RTOS. Later, when I need to perform a signature verification I do the following with a wrapper function:
ECDSA_Handle ecdsaHandle = ECDSA_open(CONFIG_ECDSA_1, nullptr); if (ecdsaHandle == nullptr) { // return error } /// Initialize the public key. CryptoKey peerPublicKey; CryptoKeyPlaintext_initKey( &peerPublicKey, uncompressedEcdsaPublicKey), // previously defined 65 byte public key (i.e. 0x04, X, Y) 65); /// Initialize the verification operation. ECDSA_OperationVerify operation; ECDSA_OperationVerify_init(&operation); operation.curve = &ECCParams_NISTP256; operation.theirPublicKey = &peerPublicKey; operation.hash = hashToVerify; // previously defined 32 byte hash operation.r = signature; // first 32 bytes of previously defined signature operation.s = signature + 32; // last 32 bytes of previously defined signature /// Verify the signature. status = ECDSA_verify(ecdsaHandle, &operation); /// Close the driver. ECDSA_close(ecdsaHandle);
As I mentioned, the ECDSA_verify() call returns -1 for a certain key, message, and signature if a BLE connection is active, but returns 0 (success) if a BLE connection is disconnected. I'm not sure why the driver is behaving differently if a BLE connection is active.
3. Could you explain me how you ported the projects? Did you start from a CC1354P10 example project and added your functionality?
- Yes, I am following TI's recommended procedure for updating to a newer SDK. I started off with CC1354P10 simple_central example project and copied over the application code from my previous codebase into this new codebase. Things seem to be working well overall except for this ECDSA issue so far.
Hi Keron,
first the updated links:
Thank you for the detailed answers.
The porting procedure seems to be correct and I'm glad to hear that the rest of the functionality works as expected.
The issue sounds like a synchronization problem. Could you check that when you call ECDSA_verify the operation and ecdsaHandle are initialized the same way when you have a connection and without?
Also please check with the debugger if ECDSA_verify actually performs the verification in both cases.
kind regards,
Theo
Hi Theo,
Thanks for the links. I was able to access them initially, but when I mentioned the 404 error, I was referring to the "change log" link referenced in the SDK release notes. The link to the change log is a dead link. I'd like to see the change log so that I can see what SDK changes have been made since sdk 7.41.00.17.
Separately, I've double-checked the things you mentioned. I've used a Watch window while running the Debugger and confirmed that the member variables of the "ECDSA_OperationVerify" and "ECDSA_Handle" objects are exactly the same with and without a connection. I've also confirmed using the debugger that ECDSA_verify performs the verification in both cases. But as mentioned, for some reason when a connection is active, ECDSA_verify returns -1 for a set of the same parameters that returned success when a connection wasn't active.
One thing I do notice when I look at the disassembly and the map file is that the code for ECDSA_verify() is located at 0x76535 and the other ECDSA-related functionality is located nearby (see attached screenshot). I believe this is flash rather than ROM. Also the map file shows that these definitions are rooted in ECDSACC26X2.c.obj. Since this is a CC13x4 processor, shouldn't the definitions come from a file like ECDSACC26X4_s.c? I'm not sure why the ECDSACC26X2.c module is being used in this codebase because I'm not including it anywhere that I'm aware of. Could this be causing some issues or do you have any other ideas?
Thanks,
Keron
Hi Keron,
thank you very much for the clarification. I confirmed that the Change Log link is down and filed a ticket to replace it.
When you define a ECDSA instance in SysConfig it is automatically including the relevant drivers. When you right-click on the project in the CCS explorer and open the project properties (Resource -> Linked Resources) you can see from where the files are imported.
Could you share a screenshot of this with me? I would like to confirm that it imports everything from the 7.41 SDK.
When you click on Build -> SysConfig and Build -> Arm Compiler in the project properties you can also verify that there it uses the 7.41 SDK.
Other than that I can just imagine that somehow the function is blocked since it has lower priority than the active link. You could try passing the data to a different thread or task context using a pointer and to perform the check outside of the connection scope.
Kind regards,
Theo
Hi Theo,
I'm using IAR 9.40.2 for my development, not CCS. Is there a way to check for what you've indicated using that configuration?
Hi Keron,
for sure. You can check in IAR as well from where the linked resources are imported.
You just need to check that it is linked from the installation directory of the 7.41 SDK.
Let me know if this is the case.
Kind regards,
Theo
Hi Theo,
Unfortunately I'm still facing this issue. Additionally, some other strange behavior I'm noticing is that when the ECDSA_verify() operation returns bad status while in a BLE connection, the GAP-related callback that usually triggers upon disconnecting never gets called. So it seems that overall the device gets into a very bad state when I see the failed ECDSA_verify operation. Do you have any ideas as to what could be happening? I'm thinking this is something beyond a resource contention issue. Please advise.
Thanks,
Keron
Hello Keron,
Could you quickly try increasing the connection interval and check if the operation still fails and how frequent it is? I wouldn't discard the resource contention issue yet. However the driver function should have resulted in ECDSA_STATUS_RESOURCE_UNAVAILABLE (-2) and not ECDSA_STATUS_ERROR (-1) if that was the case. May I ask if you are using any other encryption mechanisms on top of this one? The stack itself supports other encryption functions that might be executed along with the ECDSA function that might be causing unexpected issues. In addition, could you please set up a break point in the ECDSA_verify() function and then step over to see closer where inside the function the verification is failing and how it differs from the case where there is no connection ongoing? Lastly, could you please try increasing the ECDSA int priority to the highest to see if the behaviour reproduces?
Best Regards,
David.
Hi David,
Thanks for your reply.
1. Could you quickly try increasing the connection interval and check if the operation still fails and how frequent it is?
I've increased the connection interval to the highest possible value (i.e. 4000ms) but the operation still consistently fails. Just to provide a bit more detail...there are two calls to ECDSA_verify that I'm making during a connection. The first call always is successful. But the second call that occurs a few seconds later during the connection is always returning -1 (although the signature is valid).
2. May I ask if you are using any other encryption mechanisms on top of this one?
Yes, I have: two instances of the ECDH module, 1 ECDSA instance, 1 EDDSA instance, 1 AESCCM instance, 1 AESCTRDRBG, 1 AESECB, and 1 SHA2 instance. See attached screenshot.
3. Could you please set up a break point in the ECDSA_verify() function and then step over to see closer where inside the function the verification is failing and how it differs from the case where there is no connection ongoing?
I can't actually see the contents of ECDSA_verify() unless I include ECDSACC26X2.c in my project. Otherwise I can only see the disassembly. Assuming I should be including ECDSACC26X2.c for this exercise, when stepping inside that function, execution seems to be exactly the same whether it returns success or -1. The only difference I'm seeing is that when ECDSA_verify() calls ECDSACC26X2_waitForResult() and the ECDSA_RETURN_BEHAVIOR_BLOCKING case is hit, after the SemaphoreP_pend() call, object->operationStatus is -1 for the failed case and 0 for the successful case. However it's not clear what's causing the failure.
4. Could you please try increasing the ECDSA int priority to the highest to see if the behaviour reproduces?
Yes this was one of the first things I tried but unfortunately even an int priority of 1 didn't help. I get the same results.
BTW one more additional detail: when I get into the state when ECDSA_verify() returns bad status during a connection, UART no longer works and I have to reset the chip to get things working again. I'm thinking the chip as a whole becomes responsive. Please advise.
Thanks,
Keron
Hello Keron,
Thanks for the reply. When you mentioned that the first call to ECDSA_verify() works and the sencond does not, are both being executed inside a connection event? In addition, could you please share where in the code you are calling the wrapper function with the ECDSA functions? For example, are you calling it from a drivers callback function? Sharing more code snippets or details about the sequence of code execution will be helpful as it would appear a semaphore is pending inside a higher priority context.
Thanks.
David.
Hi David,
When you mentioned that the first call to ECDSA_verify() works and the second does not, are both being executed inside a connection event?
Both ECDSA_verify() calls are executed while my device is in an active BLE connection with a peer, but I'm not sure if they get executed while a connection event is happening on the link layer (if that's what you're asking).
In addition, could you please share where in the code you are calling the wrapper function with the ECDSA functions? For example, are you calling it from a drivers callback function?
No, I'm not executing any of this code from within a callback. I only use the pairing state callback to queue up an event that eventually kicks off the sequence of ECDSA_veridy calls from the main app task's event handler. In summary:
1. My device connects to a peer and goes through BLE pairing/bonding.
2. When the GAPBOND_PAIRING_STATE_BOND_SAVED case of the pairing state callback is reached, I queue an event that gets handled in my main application task's event handler. That event handler makes the 1st ECDSA_verify call.
3. The devices then exchange more information that leads to another event getting queued a few seconds after the 1st ECDSA_verify call. When that event gets handled by my main app task's event handler loop, the second ECDSA_verify call is made. This is the call that returns a status of -1.
Perhaps I can send you my code privately. I'll reach out to you offline.
Thanks,
Keron
Hi Keron,
I reached out to you by mail.
Let's take it from there.
Kind regards,
Theo