diff --git a/libraries/SE05X/src/SE05X.cpp b/libraries/SE05X/src/SE05X.cpp index 43801665..2da7ea03 100644 --- a/libraries/SE05X/src/SE05X.cpp +++ b/libraries/SE05X/src/SE05X.cpp @@ -69,7 +69,6 @@ SE05X_EC_SIGNATURE_RAW_LENGTH #define SE05X_SHA256_LENGTH 32 -#define SE05X_SN_LENGTH 18 #define SE05X_TEMP_OBJECT 9999 @@ -108,22 +107,35 @@ void SE05XClass::end() Se05x_API_SessionClose(&_se05x_session); } +int SE05XClass::serialNumber(byte sn[]) +{ + return serialNumber(sn, SE05X_SN_LENGTH); +} + +int SE05XClass::serialNumber(byte sn[], size_t length) +{ + size_t uidLen = length; + const int kSE05x_AppletResID_UNIQUE_ID = 0x7FFF0206; + smStatus_t status; + + status = Se05x_API_ReadObject(&_se05x_session, kSE05x_AppletResID_UNIQUE_ID, 0, length, sn, &uidLen); + if (status != SM_OK || length != uidLen) { + SMLOG_E("Error in Se05x_API_ReadObject \n"); + return 0; + } + return 1; +} + String SE05XClass::serialNumber() { String result = (char*)NULL; byte UID[SE05X_SN_LENGTH]; - size_t uidLen = SE05X_SN_LENGTH; - const int kSE05x_AppletResID_UNIQUE_ID = 0x7FFF0206, - status = Se05x_API_ReadObject(&_se05x_session, kSE05x_AppletResID_UNIQUE_ID, 0, uidLen, UID, &uidLen); - if (status != SM_OK) { - SMLOG_E("Error in Se05x_API_ReadObject \n"); - return ""; - } + serialNumber(UID, sizeof(UID)); - result.reserve(uidLen * 2); + result.reserve(SE05X_SN_LENGTH * 2); - for (size_t i = 0; i < uidLen; i++) { + for (size_t i = 0; i < SE05X_SN_LENGTH; i++) { byte b = UID[i]; if (b < 16) { @@ -168,11 +180,11 @@ int SE05XClass::random(byte data[], size_t length) smStatus_t status; uint16_t offset = 0; uint16_t left = length; - + while (left > 0) { uint16_t chunk = (left > SE05X_MAX_CHUNK_SIZE) ? SE05X_MAX_CHUNK_SIZE : left; size_t max_buffer = chunk; - + status = Se05x_API_GetRandom(&_se05x_session, chunk, (data + offset), &max_buffer); if (status != SM_OK) { SMLOG_E("Error in Se05x_API_GetRandom \n"); @@ -337,7 +349,7 @@ int SE05XClass::beginSHA256() { smStatus_t status; SE05x_CryptoModeSubType_t subtype; - + subtype.digest = kSE05x_DigestMode_SHA256; status = Se05x_API_CreateCryptoObject(&_se05x_session, kSE05x_CryptoObject_DIGEST_SHA256, kSE05x_CryptoContext_DIGEST, subtype); @@ -357,7 +369,7 @@ int SE05XClass::beginSHA256() int SE05XClass::updateSHA256(const byte in[], size_t inLen) { smStatus_t status; - + status = Se05x_API_DigestUpdate(&_se05x_session, kSE05x_CryptoObject_DIGEST_SHA256, in, inLen); if (status != SM_OK) { SMLOG_E("Error in Se05x_API_DigestUpdate \n"); @@ -374,7 +386,7 @@ int SE05XClass::endSHA256(byte out[], size_t* outLen) if (*outLen < SE05X_SHA256_LENGTH) { SMLOG_E("Error in endSHA256 \n"); *outLen = 0; - return 0; + return 0; } status = Se05x_API_DigestFinal(&_se05x_session, kSE05x_CryptoObject_DIGEST_SHA256, NULL, 0, out, outLen); @@ -530,7 +542,7 @@ int SE05XClass::ecdsaVerify(const byte message[], const byte signature[], const } if (!deleteBinaryObject(SE05X_TEMP_OBJECT)) { - SMLOG_E("ecdsaVerify failure deleting temporary object\n"); + SMLOG_E("ecdsaVerify failure deleting temporary object\n"); return 0; } @@ -574,7 +586,7 @@ int SE05XClass::readBinaryObject(int objectId, byte data[], size_t dataMaxLen, s while (left > 0) { uint16_t chunk = (left > SE05X_MAX_CHUNK_SIZE) ? SE05X_MAX_CHUNK_SIZE : left; size_t max_buffer = chunk; - + status = Se05x_API_ReadObject(&_se05x_session, objectId, offset, chunk, (data + offset), &max_buffer); if (status != SM_OK) { SMLOG_E("Error in Se05x_API_ReadObject \n"); @@ -621,8 +633,6 @@ int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length) { smStatus_t status; SE05x_Result_t result; - uint16_t offset = 0; - uint16_t size; status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result); if (status != SM_OK) { @@ -635,9 +645,7 @@ int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length) return 0; } - uint16_t left = length; - - status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 3, objectId, NULL, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_AES); + status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 3, objectId, SE05x_KeyID_KEK_NONE, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_AES); if (status != SM_OK) { SMLOG_E("Error in Se05x_API_WriteSymmKey \n"); @@ -650,9 +658,6 @@ int SE05XClass::writeHMACKey(int objectId, const byte data[], size_t length) { smStatus_t status; SE05x_Result_t result; - uint8_t exists = 0; - uint16_t offset = 0; - uint16_t size; status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result); if (status != SM_OK) { @@ -662,7 +667,6 @@ int SE05XClass::writeHMACKey(int objectId, const byte data[], size_t length) if (result == kSE05x_Result_SUCCESS) { SMLOG_E("Object exists \n"); - exists = 1; } status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 0, objectId, SE05x_KeyID_KEK_NONE, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_HMAC); @@ -784,9 +788,9 @@ int SE05XClass::getECKeyXyValuesFromDER(byte* derKey, size_t derLen, byte* rawKe if(*rawLen < SE05X_EC_KEY_RAW_LENGTH) { SMLOG_E("Error in getECKeyXyValuesFromDER \n"); *rawLen = 0; - return 0; + return 0; } - + /* XY values are stored in the last 64 bytes of DER buffer */ *rawLen = SE05X_EC_KEY_RAW_LENGTH; memcpy(rawKey, &derKey[derLen - SE05X_EC_KEY_RAW_LENGTH], SE05X_EC_KEY_RAW_LENGTH); @@ -799,15 +803,15 @@ int SE05XClass::setECKeyXyVauesInDER(const byte* rawKey, size_t rawLen, byte* de if(rawLen != SE05X_EC_KEY_RAW_LENGTH) { SMLOG_E("Error in setECKeyXyVauesInDER invalid raw key\n"); *derLen = 0; - return 0; + return 0; } if(*derLen < SE05X_EC_KEY_DER_LENGTH) { SMLOG_E("Error in setECKeyXyVauesInDER buffer too small\n"); *derLen = 0; - return 0; + return 0; } - + /* Copy header byte from 0 to 25 */ memcpy(&derKey[0], &ecc_der_header_nist256[0], SE05X_EC_KEY_DER_HEADER_LENGTH); /* Add format byte */ @@ -827,13 +831,13 @@ int SE05XClass::getECSignatureRsValuesFromDER(byte* derSignature, size_t derLen, if ((derLen < SE05X_EC_SIGNATURE_MIN_DER_LENGTH) || (derLen > SE05X_EC_SIGNATURE_MAX_DER_LENGTH)) { SMLOG_E("Error in getECSignatureRsValuesFromDER invalid signature\n"); *rawLen = 0; - return 0; + return 0; } if (*rawLen < SE05X_EC_SIGNATURE_RAW_LENGTH) { SMLOG_E("Error in getECSignatureRsValuesFromDER buffer too small\n"); *rawLen = 0; - return 0; + return 0; } rLen = derSignature[3]; @@ -868,7 +872,7 @@ int SE05XClass::setECSignatureRsValuesInDER(const byte* rawSignature, size_t raw { /** * Always consider worst case with padding - * + * * | 0x30 0x46 0x02 0x21 0x00 | R values 32 bytes | 0x02 0x21 0x00 | S values 32 bytes | * */ diff --git a/libraries/SE05X/src/SE05X.h b/libraries/SE05X/src/SE05X.h index 0ed95a60..124a82c7 100644 --- a/libraries/SE05X/src/SE05X.h +++ b/libraries/SE05X/src/SE05X.h @@ -33,6 +33,8 @@ extern "C" { } #endif +#define SE05X_SN_LENGTH 18 + class SE05XClass { public: @@ -42,6 +44,8 @@ class SE05XClass int begin(); void end(); + int serialNumber(byte sn[]); + int serialNumber(byte sn[], size_t length); #if defined (ARDUINO) String serialNumber(); #endif @@ -65,7 +69,7 @@ class SE05XClass * @return 0 on Failure 1 on Success */ int generatePrivateKey(int keyID, byte keyBuf[], size_t keyBufMaxLen, size_t* keyLen); - + /** generatePublicKey * * Reads ECCurve_NIST_P256 public key from KeyID. Public key will be available @@ -114,7 +118,7 @@ class SE05XClass * @param[in] inLen Input data length * * @return 0 on Failure 1 on Success - */ + */ int updateSHA256(const byte in[], size_t inLen); /** endSHA256 @@ -125,9 +129,9 @@ class SE05XClass * @param[in,out] outLen Size of output data buffer, SHA256 length * * @return 0 on Failure 1 on Success - */ + */ int endSHA256(byte out[], size_t* outLen); - + /** SHA256 * * One-shot SHA256 @@ -139,15 +143,15 @@ class SE05XClass * @param[out] outLen SHA256 length * * @return 0 on Failure 1 on Success - */ + */ int SHA256(const byte in[], size_t inLen, byte out[], size_t outMaxLen, size_t* outLen); /** Sign * * Computes ECDSA signature using key stored in KeyID SE050 object. * Output buffer is filled with the signature in DER format: - * - * | 0x30 | payloadsize 1 byte | 0x02 | R length 1 byte | padding 0x00 (if length 0x21) | R values 32 bytes + * + * | 0x30 | payloadsize 1 byte | 0x02 | R length 1 byte | padding 0x00 (if length 0x21) | R values 32 bytes * | 0x02 | S length 1 byte | padding 0x00 (if length 0x21) | S values 32 bytes * * SHA256 -> private Key -> Signature @@ -160,7 +164,7 @@ class SE05XClass * @param[out] sigLen signature length * * @return 0 on Failure 1 on Success - */ + */ int Sign(int keyID, const byte hash[], size_t hashLen, byte sig[], size_t maxSigLen, size_t* sigLen); /** Verify @@ -170,7 +174,7 @@ class SE05XClass * Input SHA256 * ? Match ? * Signature -> public Key -> Original SHA256 - * + * * @param[in] keyID SE050 object ID containing the key * @param[in] hash Input SHA256 used to compute the signature * @param[in] hashLen SHA256 length @@ -178,20 +182,20 @@ class SE05XClass * @param[in] sigLen signature length * * @return 0 on Failure (Not match) 1 on Success (Match) - */ + */ int Verify(int keyID, const byte hash[], size_t hashLen, const byte sig[],size_t sigLen); /** readBinaryObject * * Reads binary data from SE050 object. - * + * * @param[in] ObjectId SE050 object ID containing data * @param[out] data Output data buffer * @param[in] dataMaxLen Output data buffer size * @param[out] sig Binary object size * * @return 0 on Failure 1 on Success - */ + */ int readBinaryObject(int ObjectId, byte data[], size_t dataMaxLen, size_t* length); /** AES_ECB_encrypt @@ -265,43 +269,43 @@ class SE05XClass /** writeBinaryObject * * Writes binary data into SE050 object. - * + * * @param[in] ObjectId SE050 object ID * @param[in] data Input data buffer * @param[in] length Input data buffer size * * @return 0 on Failure 1 on Success - */ + */ int writeBinaryObject(int ObjectId, const byte data[], size_t length); /** existsBinaryObject * * Checks if Object exist - * + * * @param[in] ObjectId SE050 object ID * * @return 0 on Failure (Not exist) 1 on Success (Exists) - */ + */ int existsBinaryObject(int objectId); /** deleteBinaryObject * * Deletes SE050 object - * + * * @param[in] ObjectId SE050 object ID * * @return 0 on Failure 1 on Success - */ + */ int deleteBinaryObject(int objectId); /** deleteBinaryObject * * Deletes all SE050 user objects - * + * * @param[in] ObjectId SE050 object ID * * @return 0 on Failure 1 on Success - */ + */ int deleteAllObjects(); /* ECCX08 legacy API*/ @@ -341,20 +345,20 @@ class SE05XClass * Input SHA256 * ? Match ? * Signature -> public Key -> Original SHA256 - * + * * @param[in] message Input SHA256 used to compute the signature 32 bytes * @param[in] sig Input buffer containint the signature R S values 64bytes * @param[in] pubkey Public key X Y values 64bytes * * @return 0 on Failure (Not match) 1 on Success (Match) - */ + */ int ecdsaVerify(const byte message[], const byte signature[], const byte pubkey[]); /** ecSign * * Computes ECDSA signature using key stored in KeyID SE050 object. * Output buffer is filled with the signature R S values: - * + * * | R values 32 bytes | S values 32 bytes | * * SHA256 -> private Key -> Signature @@ -364,36 +368,36 @@ class SE05XClass * @param[out] signature Output buffer containint the signature 64 bytes * * @return 0 on Failure 1 on Success - */ + */ int ecSign(int slot, const byte message[], byte signature[]); /** readSlot * * Reads binary data from SE050 object. - * + * * @param[in] ObjecslottId SE050 object ID containing data * @param[out] data Output data buffer * @param[in] length Number of bytes to read * * @return 0 on Failure 1 on Success - */ + */ int readSlot(int slot, byte data[], int length); /** writeSlot * * Writes binary data into SE050 object. - * + * * @param[in] ObjectId SE050 object ID * @param[in] data Input data buffer * @param[in] length Number of bytes to write * * @return 0 on Failure 1 on Success - */ + */ int writeSlot(int slot, const byte data[], int length); inline int locked() { return 1; } inline int lock() { return 1; } - inline int writeConfiguration(const byte data[]) { return 1; } + inline int writeConfiguration(const byte data[]) { (void)data; return 1; } inline Se05xSession_t* getSession() { return &_se05x_session; } private: