@@ -170,6 +170,35 @@ static int _getCryptoResponse(uint8_t* respBuf, uint16_t type,
170170 return header -> rc ;
171171}
172172
173+ #if !defined(NO_HMAC )
174+ #define WH_CLIENT_HMAC_PACK_IDS (_keyId , _stateId ) \
175+ ((uintptr_t)((((uintptr_t)(_stateId) & 0xFFFFu) << 16) | \
176+ ((uintptr_t)(_keyId) & 0xFFFFu)))
177+
178+ static uint16_t _wh_Client_HmacGetKeyId (const Hmac * hmac )
179+ {
180+ return (uint16_t )(((uintptr_t )hmac -> devCtx ) & 0xFFFFu );
181+ }
182+
183+ static uint16_t _wh_Client_HmacGetStateId (const Hmac * hmac )
184+ {
185+ return (uint16_t )((((uintptr_t )hmac -> devCtx ) >> 16 ) & 0xFFFFu );
186+ }
187+
188+ static void _wh_Client_HmacSetIds (Hmac * hmac , uint16_t keyId , uint16_t stateId )
189+ {
190+ hmac -> devCtx = (void * )WH_CLIENT_HMAC_PACK_IDS (keyId , stateId );
191+ }
192+
193+ static int _wh_Client_HmacSend (whClientContext * ctx ,
194+ whMessageCrypto_hmacOperation op , int hashType ,
195+ uint16_t keyId , uint16_t stateId ,
196+ const uint8_t * key , uint32_t keyLen ,
197+ const uint8_t * in , uint32_t inLen ,
198+ uint8_t * out , uint32_t outCapacity ,
199+ uint16_t * outStateId , uint32_t * outSz );
200+ #endif /* !NO_HMAC */
201+
173202/** Implementations */
174203int wh_Client_RngGenerate (whClientContext * ctx , uint8_t * out , uint32_t size )
175204{
@@ -2758,6 +2787,188 @@ int wh_Client_AesGetKeyId(Aes* key, whNvmId* outId)
27582787}
27592788#endif
27602789
2790+ #if !defined(NO_HMAC )
2791+ int wh_Client_HmacSetKeyId (Hmac * hmac , whKeyId keyId )
2792+ {
2793+ if ((hmac == NULL ) || WH_KEYID_ISERASED (keyId )) {
2794+ return WH_ERROR_BADARGS ;
2795+ }
2796+
2797+ _wh_Client_HmacSetIds (hmac , keyId , 0 );
2798+ return WH_ERROR_OK ;
2799+ }
2800+
2801+ static int _wh_Client_HmacSend (whClientContext * ctx ,
2802+ whMessageCrypto_hmacOperation op , int hashType ,
2803+ uint16_t keyId , uint16_t stateId ,
2804+ const uint8_t * key , uint32_t keyLen ,
2805+ const uint8_t * in , uint32_t inLen ,
2806+ uint8_t * out , uint32_t outCapacity ,
2807+ uint16_t * outStateId , uint32_t * outSz )
2808+ {
2809+ if (ctx == NULL || (keyLen > 0 && key == NULL ) ||
2810+ (inLen > 0 && in == NULL )) {
2811+ return WH_ERROR_BADARGS ;
2812+ }
2813+
2814+ uint8_t * dataPtr = (uint8_t * )wh_CommClient_GetDataPtr (ctx -> comm );
2815+ if (dataPtr == NULL ) {
2816+ return WH_ERROR_BADARGS ;
2817+ }
2818+
2819+ uint32_t payloadLen =
2820+ sizeof (whMessageCrypto_GenericRequestHeader ) +
2821+ sizeof (whMessageCrypto_HmacRequest ) + keyLen + inLen ;
2822+ if (payloadLen > WOLFHSM_CFG_COMM_DATA_LEN ) {
2823+ return WH_ERROR_BADARGS ;
2824+ }
2825+
2826+ whMessageCrypto_HmacRequest * req =
2827+ (whMessageCrypto_HmacRequest * )_createCryptoRequest (
2828+ dataPtr , WC_ALGO_TYPE_HMAC );
2829+
2830+ req -> hashType = (uint32_t )hashType ;
2831+ req -> keySz = keyLen ;
2832+ req -> inSz = inLen ;
2833+ req -> keyId = keyId ;
2834+ req -> stateId = stateId ;
2835+ req -> hmacOp = (uint16_t )op ;
2836+ req -> flags = 0 ;
2837+
2838+ uint8_t * idx = (uint8_t * )(req + 1 );
2839+ if (keyLen > 0U ) {
2840+ if (key == NULL ) {
2841+ return WH_ERROR_BADARGS ;
2842+ }
2843+ memcpy (idx , key , keyLen );
2844+ idx += keyLen ;
2845+ }
2846+ if (inLen > 0U ) {
2847+ if (in == NULL ) {
2848+ return WH_ERROR_BADARGS ;
2849+ }
2850+ memcpy (idx , in , inLen );
2851+ idx += inLen ;
2852+ }
2853+
2854+ int ret = wh_Client_SendRequest (ctx , WH_MESSAGE_GROUP_CRYPTO ,
2855+ WC_ALGO_TYPE_HMAC , (uint16_t )payloadLen ,
2856+ dataPtr );
2857+ if (ret != WH_ERROR_OK ) {
2858+ return ret ;
2859+ }
2860+
2861+ uint16_t respGroup ;
2862+ uint16_t respAction ;
2863+ uint16_t respSize ;
2864+ do {
2865+ ret = wh_Client_RecvResponse (ctx , & respGroup , & respAction , & respSize ,
2866+ dataPtr );
2867+ } while (ret == WH_ERROR_NOTREADY );
2868+ if (ret != WH_ERROR_OK ) {
2869+ return ret ;
2870+ }
2871+ if ((respGroup != WH_MESSAGE_GROUP_CRYPTO ) ||
2872+ (respAction != WC_ALGO_TYPE_HMAC )) {
2873+ return WH_ERROR_ABORTED ;
2874+ }
2875+
2876+ whMessageCrypto_HmacResponse * resp = NULL ;
2877+ ret = _getCryptoResponse (dataPtr , WC_ALGO_TYPE_HMAC , (uint8_t * * )& resp );
2878+ if (ret < 0 ) {
2879+ return ret ;
2880+ }
2881+
2882+ if (outStateId != NULL ) {
2883+ * outStateId = resp -> stateId ;
2884+ }
2885+ if (outSz != NULL ) {
2886+ * outSz = resp -> outSz ;
2887+ }
2888+
2889+ if (resp -> outSz > 0U ) {
2890+ uint8_t * respData = (uint8_t * )(resp + 1 );
2891+ if ((out == NULL ) || (resp -> outSz > outCapacity )) {
2892+ return WH_ERROR_NOSPACE ;
2893+ }
2894+ memcpy (out , respData , resp -> outSz );
2895+ }
2896+
2897+ return ret ;
2898+ }
2899+
2900+ int wh_Client_Hmac (whClientContext * ctx , Hmac * hmac , int macType ,
2901+ const uint8_t * in , uint32_t inLen , uint8_t * digest )
2902+ {
2903+ if ((ctx == NULL ) || (hmac == NULL ) || (in == NULL && inLen > 0 )) {
2904+ return WH_ERROR_BADARGS ;
2905+ }
2906+
2907+ uint16_t keyId = _wh_Client_HmacGetKeyId (hmac );
2908+ uint16_t stateId = _wh_Client_HmacGetStateId (hmac );
2909+ uint32_t digestSz ;
2910+ const uint8_t * keyBuf = NULL ;
2911+ uint32_t keyLen = 0 ;
2912+ int ret = WH_ERROR_OK ;
2913+
2914+ /* send inline key only on on first use */
2915+ if (stateId == 0U && keyId == WH_KEYID_ERASED ) {
2916+ if (hmac -> keyLen == 0U || hmac -> keyRaw == NULL ) {
2917+ return WH_ERROR_BADARGS ;
2918+ }
2919+ keyBuf = hmac -> keyRaw ;
2920+ keyLen = hmac -> keyLen ;
2921+ }
2922+
2923+ /* get digest size */
2924+ if (digest != NULL ) {
2925+ ret = wc_HmacSizeByType (macType );
2926+ if (ret < 0 ) {
2927+ return ret ;
2928+ }
2929+ digestSz = ret ;
2930+ }
2931+
2932+ /* one shot operation */
2933+ if (digest != NULL && stateId == 0 ) {
2934+ /* stateId must be 0 for one shot */
2935+ if (stateId != 0U ) {
2936+ return WH_ERROR_BADARGS ;
2937+ }
2938+
2939+ ret = _wh_Client_HmacSend (ctx , WH_MESSAGE_CRYPTO_HMAC_OP_ONESHOT ,
2940+ macType , keyId , stateId , keyBuf , keyLen , in ,
2941+ inLen , digest , digestSz , NULL ,
2942+ & digestSz );
2943+ if (ret < 0 ) {
2944+ return ret ;
2945+ }
2946+ }
2947+ /* update only operation */
2948+ else if (digest == NULL ) {
2949+ ret = _wh_Client_HmacSend (ctx , WH_MESSAGE_CRYPTO_HMAC_OP_UPDATE ,
2950+ macType , keyId , stateId , keyBuf , keyLen , in ,
2951+ inLen , NULL , 0 , & stateId , NULL );
2952+ if (ret < 0 ) {
2953+ return ret ;
2954+ }
2955+ _wh_Client_HmacSetIds (hmac , keyId , stateId );
2956+ }
2957+ /* final only operation */
2958+ else {
2959+ ret = _wh_Client_HmacSend (ctx , WH_MESSAGE_CRYPTO_HMAC_OP_FINAL ,
2960+ macType , keyId , stateId , keyBuf , keyLen , NULL , 0 ,
2961+ digest , digestSz , NULL , & digestSz );
2962+ if (ret < 0 ) {
2963+ return ret ;
2964+ }
2965+ _wh_Client_HmacSetIds (hmac , keyId , 0 );
2966+ }
2967+
2968+ return ret ;
2969+ }
2970+ #endif /* !NO_HMAC */
2971+
27612972#ifdef WOLFSSL_CMAC
27622973int wh_Client_CmacSetKeyId (Cmac * key , whNvmId keyId )
27632974{
0 commit comments