Kaynağa Gözat

fix hmac method

dreamcmi 3 yıl önce
ebeveyn
işleme
2491fa71b2

+ 16 - 0
examples/hmac/test_hmac.py

@@ -0,0 +1,16 @@
+import hmac
+
+secret = "0123456789"
+payload = "helloworld"
+
+h = hmac.new(secret.encode(),digestmod="hmac-md5")
+h.update(payload.encode())
+print("hmac-md5:",h.hexdigest())
+
+h = hmac.new(secret.encode(),digestmod="hmac-sha1")
+h.update(payload.encode())
+print("hmac-sha1:",h.hexdigest())
+
+h = hmac.new(secret.encode(),digestmod="hmac-sha256")
+h.update(payload.encode())
+print("hmac-sha256:",h.hexdigest())

+ 43 - 222
package/hmac/_hmac_HMAC.c

@@ -1,11 +1,7 @@
 #include "_hmac_HMAC.h"
-
+#include "mbedtls/md.h"
 #include "string.h"
 
-#include "mbedtls/md5.h"
-#include "mbedtls/sha1.h"
-#include "mbedtls/sha256.h"
-
 enum {
     PIKA_HMAC_MD5 = 16,
     PIKA_HMAC_SHA1 = 20,
@@ -20,214 +16,80 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) {
     if (ARG_TYPE_NONE != t) {
         if (ARG_TYPE_BYTES != t) {
             obj_setErrorCode(self, -2);  // io error
+            obj_setSysOut(self, "hmac.new() key type error");
         }
     }
     t = arg_getType(msg);
     if (ARG_TYPE_NONE != t) {
         if (ARG_TYPE_BYTES != t) {
             obj_setErrorCode(self, -2);  // io error
+            obj_setSysOut(self, "hmac.new() msg type error");
         }
     }
 
-    obj_setInt(self, "_digest_flags", 0);                 // flag
-    obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256);  // digest buff
-    obj_setBytes(self, "_hexbuff", NULL,
-                 PIKA_HMAC_SHA256 * 2);      // hexdigest buff
-    obj_setBytes(self, "_k_ipad", NULL, 64);  // key ipad
-    obj_setBytes(self, "_k_opad", NULL, 64);  // key opad
-
     size_t key_len = arg_getBytesSize(key);
     uint8_t* key_data = arg_getBytes(key);
     size_t msg_len = arg_getBytesSize(msg);
     uint8_t* msg_data = arg_getBytes(msg);
-
-    uint8_t* k_ipad = obj_getBytes(self, "_k_ipad");
-    uint8_t* k_opad = obj_getBytes(self, "_k_opad");
+    obj_setInt(self, "_digest_flags", 0);                 // flag
+    obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256);  // digest buff
+    obj_setBytes(self, "_hexbuff", NULL, PIKA_HMAC_SHA256 * 2);
+    memset(obj_getBytes(self, "_buff"), 0, PIKA_HMAC_SHA256);
+    memset(obj_getBytes(self, "_hexbuff"), 0, PIKA_HMAC_SHA256 * 2);
+    mbedtls_md_context_t ctx;
+    mbedtls_md_init(&ctx);
 
     if (strcmp(digestmod, "hmac-md5") == 0 ||
         strcmp(digestmod, "HMAC-MD5") == 0) {
-        mbedtls_md5_context context;
-
-        if (key_len > 64) {
-            mbedtls_md5_init(&context);
-            mbedtls_md5_starts(&context);
-            mbedtls_md5_update(&context, key_data, key_len);
-            mbedtls_md5_finish(&context, k_ipad);
-            mbedtls_md5_free(&context);
-            memcpy(k_opad, k_ipad, 64);
-        } else {
-            memcpy(k_ipad, key_data, key_len);
-            memcpy(k_opad, key_data, key_len);
-        }
-
-        for (size_t i = 0; i < 64; i++) {
-            k_ipad[i] ^= 0x36;
-            k_opad[i] ^= 0x5c;
-        }
-
-        mbedtls_md5_init(&context);
-        mbedtls_md5_starts(&context);
-        mbedtls_md5_update(&context, k_ipad, 64);
-        if (msg_len > 0) {
-            mbedtls_md5_update(&context, msg_data, msg_len);
-        }
-
-        obj_setStruct(self, "context", context);
-        obj_setInt(self, "mode", PIKA_HMAC_MD5);
+        mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1);
+        obj_setInt(self, "_mode", PIKA_HMAC_MD5);
     } else if (strcmp(digestmod, "hmac-sha1") == 0 ||
                strcmp(digestmod, "HMAC-SHA1") == 0) {
-        mbedtls_sha1_context context;
-
-        if (key_len > 64) {
-            mbedtls_sha1_init(&context);
-            mbedtls_sha1_starts(&context);
-            mbedtls_sha1_update(&context, key_data, key_len);
-            mbedtls_sha1_finish(&context, k_ipad);
-            mbedtls_sha1_free(&context);
-            memcpy(k_opad, k_ipad, 64);
-        } else {
-            memcpy(k_ipad, key_data, key_len);
-            memcpy(k_opad, key_data, key_len);
-        }
-
-        for (size_t i = 0; i < 64; i++) {
-            k_ipad[i] ^= 0x36;
-            k_opad[i] ^= 0x5c;
-        }
-
-        mbedtls_sha1_init(&context);
-        mbedtls_sha1_starts(&context);
-        mbedtls_sha1_update(&context, k_ipad, 64);
-        if (msg_len > 0) {
-            mbedtls_sha1_update(&context, msg_data, msg_len);
-        }
-
-        obj_setStruct(self, "context", context);
-        obj_setInt(self, "mode", PIKA_HMAC_SHA1);
+        mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1);
+        obj_setInt(self, "_mode", PIKA_HMAC_SHA1);
     } else if (strcmp(digestmod, "hmac-sha256") == 0 ||
                strcmp(digestmod, "HMAC-SHA256") == 0) {
-        mbedtls_sha256_context context;
-
-        if (key_len > 64) {
-            mbedtls_sha256_init(&context);
-            mbedtls_sha256_starts(&context, 0);
-            mbedtls_sha256_update(&context, key_data, key_len);
-            mbedtls_sha256_finish(&context, k_ipad);
-            mbedtls_sha256_free(&context);
-            memcpy(k_opad, k_ipad, 64);
-        } else {
-            memcpy(k_ipad, key_data, key_len);
-            memcpy(k_opad, key_data, key_len);
-        }
-
-        for (size_t i = 0; i < 64; i++) {
-            k_ipad[i] ^= 0x36;
-            k_opad[i] ^= 0x5c;
-        }
-
-        mbedtls_sha256_init(&context);
-        mbedtls_sha256_starts(&context, 0);
-        mbedtls_sha256_update(&context, k_ipad, 64);
-        if (msg_len > 0) {
-            mbedtls_sha256_update(&context, msg_data, msg_len);
-        }
-
-        obj_setStruct(self, "context", context);
-        obj_setInt(self, "mode", PIKA_HMAC_SHA256);
+        mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1);
+        obj_setInt(self, "_mode", PIKA_HMAC_SHA256);
     } else {
-        obj_setErrorCode(self, -1);  // not support mode
+        obj_setErrorCode(self, -2);  // io error
+        obj_setSysOut(self, "hmac.new() not support mode");
     }
+    mbedtls_md_hmac_starts(&ctx, key_data, key_len);
+    if (msg_len > 0) {
+        mbedtls_md_hmac_update(&ctx, msg_data, msg_len);
+    }
+    obj_setStruct(self, "_context", ctx);
 }
 
 void _hmac_HMAC_update(PikaObj* self, Arg* msg) {
     ArgType t = arg_getType(msg);
     if (ARG_TYPE_BYTES != t) {
         obj_setErrorCode(self, -2);  // io error
+        obj_setSysOut(self, "hmac.update() msg type error");
     }
 
     size_t msg_len = arg_getBytesSize(msg);
     uint8_t* msg_data = arg_getBytes(msg);
-    void* context = obj_getStruct(self, "context");
-
-    if (msg_len > 0) {
-        switch (obj_getInt(self, "mode")) {
-            case PIKA_HMAC_MD5:
-                mbedtls_md5_update((mbedtls_md5_context*)context, msg_data,
-                                   msg_len);
-                break;
-            case PIKA_HMAC_SHA1:
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, msg_data,
-                                    msg_len);
-                break;
-            case PIKA_HMAC_SHA256:
-                mbedtls_sha256_update((mbedtls_sha256_context*)context,
-                                      msg_data, msg_len);
-                break;
-            default:
-                break;
-        }
-    } else {
-        obj_setErrorCode(self, -2);  // io error
-    }
+    mbedtls_md_context_t* ctx = obj_getStruct(self, "_context");
+    mbedtls_md_hmac_update(ctx, msg_data, msg_len);
 }
 
 Arg* _hmac_HMAC_digest(PikaObj* self) {
-    uint8_t* k_opad = obj_getBytes(self, "_k_opad");
     uint8_t* buff = obj_getBytes(self, "_buff");
     uint8_t flag = obj_getInt(self, "_digest_flags");
 
     if (flag & 0x01)  // already digest
     {
-        return arg_newBytes(buff, obj_getInt(self, "mode"));
+        goto exit;
     } else {
-        void* context = obj_getStruct(self, "context");
-        uint8_t mode = obj_getInt(self, "mode");
-        switch (mode) {
-            case PIKA_HMAC_MD5:
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-
-                mbedtls_md5_init((mbedtls_md5_context*)context);
-                mbedtls_md5_starts((mbedtls_md5_context*)context);
-                mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64);
-                mbedtls_md5_update((mbedtls_md5_context*)context, buff,
-                                   PIKA_HMAC_MD5);
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-                break;
-            case PIKA_HMAC_SHA1:
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-
-                mbedtls_sha1_init((mbedtls_sha1_context*)context);
-                mbedtls_sha1_starts((mbedtls_sha1_context*)context);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, buff,
-                                    PIKA_HMAC_SHA1);
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-                break;
-            case PIKA_HMAC_SHA256:
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-
-                mbedtls_sha256_init((mbedtls_sha256_context*)context);
-                mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad,
-                                      64);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, buff,
-                                      PIKA_HMAC_SHA256);
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-                break;
-            default:
-                obj_setErrorCode(self, -1);  // not support mode
-                return arg_newNull();  // will not actually return to the python
-                break;
-        }
+        mbedtls_md_context_t* ctx = obj_getStruct(self, "_context");
+        mbedtls_md_hmac_finish(ctx, buff);
         obj_setInt(self, "_digest_flags", flag | 0x01);
-        return arg_newBytes(buff, mode);
+        goto exit;
     }
+exit:
+    return arg_newBytes(buff, obj_getInt(self, "_mode"));
 }
 
 char* _hmac_HMAC_hexdigest(PikaObj* self) {
@@ -235,61 +97,20 @@ char* _hmac_HMAC_hexdigest(PikaObj* self) {
     uint8_t* hexbuff = obj_getBytes(self, "_hexbuff");
     uint8_t flag = obj_getInt(self, "_digest_flags");
 
-    if (flag & 0x01) {  // already digest
-        hmac_to_hex(buff, obj_getInt(self, "mode"), hexbuff);
+    if (flag & 0x01) {                                   // already digest
         obj_setInt(self, "_digest_flags", flag | 0x02);  // set hexdigest flag
-    } else if (flag & 0x02) {                           // already hexdigest
-
+        goto exit;
+    } else if (flag & 0x02) {  // already hexdigest
+        return (char*)hexbuff;
     } else {
-        void* context = obj_getStruct(self, "context");
-        uint8_t* k_opad = obj_getBytes(self, "_k_opad");
-
-        switch (obj_getInt(self, "mode")) {
-            case PIKA_HMAC_MD5:
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-
-                mbedtls_md5_init((mbedtls_md5_context*)context);
-                mbedtls_md5_starts((mbedtls_md5_context*)context);
-                mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64);
-                mbedtls_md5_update((mbedtls_md5_context*)context, buff,
-                                   PIKA_HMAC_MD5);
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-                break;
-            case PIKA_HMAC_SHA1:
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-
-                mbedtls_sha1_init((mbedtls_sha1_context*)context);
-                mbedtls_sha1_starts((mbedtls_sha1_context*)context);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, buff,
-                                    PIKA_HMAC_SHA1);
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-                break;
-            case PIKA_HMAC_SHA256:
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-
-                mbedtls_sha256_init((mbedtls_sha256_context*)context);
-                mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad,
-                                      64);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, buff,
-                                      PIKA_HMAC_SHA256);
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-                break;
-            default:
-                obj_setErrorCode(self, -1);  // not support mode
-                break;
-        }
-        hmac_to_hex(buff, PIKA_HMAC_MD5, hexbuff);
-        obj_setInt(self, "_digest_flags",
-                   flag | 0x03);  // set digest and hexdigest flags
+        mbedtls_md_context_t* ctx = obj_getStruct(self, "_context");
+        mbedtls_md_hmac_finish(ctx, buff);
+        // set digest and hexdigest flags
+        obj_setInt(self, "_digest_flags", flag | 0x03);
+        goto exit;
     }
+exit:
+    hmac_to_hex(buff, obj_getInt(self, "_mode"), hexbuff);
     return (char*)hexbuff;
 }
 

+ 43 - 222
port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c

@@ -1,11 +1,7 @@
 #include "_hmac_HMAC.h"
-
+#include "mbedtls/md.h"
 #include "string.h"
 
-#include "mbedtls/md5.h"
-#include "mbedtls/sha1.h"
-#include "mbedtls/sha256.h"
-
 enum {
     PIKA_HMAC_MD5 = 16,
     PIKA_HMAC_SHA1 = 20,
@@ -20,214 +16,80 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) {
     if (ARG_TYPE_NONE != t) {
         if (ARG_TYPE_BYTES != t) {
             obj_setErrorCode(self, -2);  // io error
+            obj_setSysOut(self, "hmac.new() key type error");
         }
     }
     t = arg_getType(msg);
     if (ARG_TYPE_NONE != t) {
         if (ARG_TYPE_BYTES != t) {
             obj_setErrorCode(self, -2);  // io error
+            obj_setSysOut(self, "hmac.new() msg type error");
         }
     }
 
-    obj_setInt(self, "_digest_flags", 0);                 // flag
-    obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256);  // digest buff
-    obj_setBytes(self, "_hexbuff", NULL,
-                 PIKA_HMAC_SHA256 * 2);      // hexdigest buff
-    obj_setBytes(self, "_k_ipad", NULL, 64);  // key ipad
-    obj_setBytes(self, "_k_opad", NULL, 64);  // key opad
-
     size_t key_len = arg_getBytesSize(key);
     uint8_t* key_data = arg_getBytes(key);
     size_t msg_len = arg_getBytesSize(msg);
     uint8_t* msg_data = arg_getBytes(msg);
-
-    uint8_t* k_ipad = obj_getBytes(self, "_k_ipad");
-    uint8_t* k_opad = obj_getBytes(self, "_k_opad");
+    obj_setInt(self, "_digest_flags", 0);                 // flag
+    obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256);  // digest buff
+    obj_setBytes(self, "_hexbuff", NULL, PIKA_HMAC_SHA256 * 2);
+    memset(obj_getBytes(self, "_buff"), 0, PIKA_HMAC_SHA256);
+    memset(obj_getBytes(self, "_hexbuff"), 0, PIKA_HMAC_SHA256 * 2);
+    mbedtls_md_context_t ctx;
+    mbedtls_md_init(&ctx);
 
     if (strcmp(digestmod, "hmac-md5") == 0 ||
         strcmp(digestmod, "HMAC-MD5") == 0) {
-        mbedtls_md5_context context;
-
-        if (key_len > 64) {
-            mbedtls_md5_init(&context);
-            mbedtls_md5_starts(&context);
-            mbedtls_md5_update(&context, key_data, key_len);
-            mbedtls_md5_finish(&context, k_ipad);
-            mbedtls_md5_free(&context);
-            memcpy(k_opad, k_ipad, 64);
-        } else {
-            memcpy(k_ipad, key_data, key_len);
-            memcpy(k_opad, key_data, key_len);
-        }
-
-        for (size_t i = 0; i < 64; i++) {
-            k_ipad[i] ^= 0x36;
-            k_opad[i] ^= 0x5c;
-        }
-
-        mbedtls_md5_init(&context);
-        mbedtls_md5_starts(&context);
-        mbedtls_md5_update(&context, k_ipad, 64);
-        if (msg_len > 0) {
-            mbedtls_md5_update(&context, msg_data, msg_len);
-        }
-
-        obj_setStruct(self, "context", context);
-        obj_setInt(self, "mode", PIKA_HMAC_MD5);
+        mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1);
+        obj_setInt(self, "_mode", PIKA_HMAC_MD5);
     } else if (strcmp(digestmod, "hmac-sha1") == 0 ||
                strcmp(digestmod, "HMAC-SHA1") == 0) {
-        mbedtls_sha1_context context;
-
-        if (key_len > 64) {
-            mbedtls_sha1_init(&context);
-            mbedtls_sha1_starts(&context);
-            mbedtls_sha1_update(&context, key_data, key_len);
-            mbedtls_sha1_finish(&context, k_ipad);
-            mbedtls_sha1_free(&context);
-            memcpy(k_opad, k_ipad, 64);
-        } else {
-            memcpy(k_ipad, key_data, key_len);
-            memcpy(k_opad, key_data, key_len);
-        }
-
-        for (size_t i = 0; i < 64; i++) {
-            k_ipad[i] ^= 0x36;
-            k_opad[i] ^= 0x5c;
-        }
-
-        mbedtls_sha1_init(&context);
-        mbedtls_sha1_starts(&context);
-        mbedtls_sha1_update(&context, k_ipad, 64);
-        if (msg_len > 0) {
-            mbedtls_sha1_update(&context, msg_data, msg_len);
-        }
-
-        obj_setStruct(self, "context", context);
-        obj_setInt(self, "mode", PIKA_HMAC_SHA1);
+        mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1);
+        obj_setInt(self, "_mode", PIKA_HMAC_SHA1);
     } else if (strcmp(digestmod, "hmac-sha256") == 0 ||
                strcmp(digestmod, "HMAC-SHA256") == 0) {
-        mbedtls_sha256_context context;
-
-        if (key_len > 64) {
-            mbedtls_sha256_init(&context);
-            mbedtls_sha256_starts(&context, 0);
-            mbedtls_sha256_update(&context, key_data, key_len);
-            mbedtls_sha256_finish(&context, k_ipad);
-            mbedtls_sha256_free(&context);
-            memcpy(k_opad, k_ipad, 64);
-        } else {
-            memcpy(k_ipad, key_data, key_len);
-            memcpy(k_opad, key_data, key_len);
-        }
-
-        for (size_t i = 0; i < 64; i++) {
-            k_ipad[i] ^= 0x36;
-            k_opad[i] ^= 0x5c;
-        }
-
-        mbedtls_sha256_init(&context);
-        mbedtls_sha256_starts(&context, 0);
-        mbedtls_sha256_update(&context, k_ipad, 64);
-        if (msg_len > 0) {
-            mbedtls_sha256_update(&context, msg_data, msg_len);
-        }
-
-        obj_setStruct(self, "context", context);
-        obj_setInt(self, "mode", PIKA_HMAC_SHA256);
+        mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1);
+        obj_setInt(self, "_mode", PIKA_HMAC_SHA256);
     } else {
-        obj_setErrorCode(self, -1);  // not support mode
+        obj_setErrorCode(self, -2);  // io error
+        obj_setSysOut(self, "hmac.new() not support mode");
     }
+    mbedtls_md_hmac_starts(&ctx, key_data, key_len);
+    if (msg_len > 0) {
+        mbedtls_md_hmac_update(&ctx, msg_data, msg_len);
+    }
+    obj_setStruct(self, "_context", ctx);
 }
 
 void _hmac_HMAC_update(PikaObj* self, Arg* msg) {
     ArgType t = arg_getType(msg);
     if (ARG_TYPE_BYTES != t) {
         obj_setErrorCode(self, -2);  // io error
+        obj_setSysOut(self, "hmac.update() msg type error");
     }
 
     size_t msg_len = arg_getBytesSize(msg);
     uint8_t* msg_data = arg_getBytes(msg);
-    void* context = obj_getStruct(self, "context");
-
-    if (msg_len > 0) {
-        switch (obj_getInt(self, "mode")) {
-            case PIKA_HMAC_MD5:
-                mbedtls_md5_update((mbedtls_md5_context*)context, msg_data,
-                                   msg_len);
-                break;
-            case PIKA_HMAC_SHA1:
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, msg_data,
-                                    msg_len);
-                break;
-            case PIKA_HMAC_SHA256:
-                mbedtls_sha256_update((mbedtls_sha256_context*)context,
-                                      msg_data, msg_len);
-                break;
-            default:
-                break;
-        }
-    } else {
-        obj_setErrorCode(self, -2);  // io error
-    }
+    mbedtls_md_context_t* ctx = obj_getStruct(self, "_context");
+    mbedtls_md_hmac_update(ctx, msg_data, msg_len);
 }
 
 Arg* _hmac_HMAC_digest(PikaObj* self) {
-    uint8_t* k_opad = obj_getBytes(self, "_k_opad");
     uint8_t* buff = obj_getBytes(self, "_buff");
     uint8_t flag = obj_getInt(self, "_digest_flags");
 
     if (flag & 0x01)  // already digest
     {
-        return arg_newBytes(buff, obj_getInt(self, "mode"));
+        goto exit;
     } else {
-        void* context = obj_getStruct(self, "context");
-        uint8_t mode = obj_getInt(self, "mode");
-        switch (mode) {
-            case PIKA_HMAC_MD5:
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-
-                mbedtls_md5_init((mbedtls_md5_context*)context);
-                mbedtls_md5_starts((mbedtls_md5_context*)context);
-                mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64);
-                mbedtls_md5_update((mbedtls_md5_context*)context, buff,
-                                   PIKA_HMAC_MD5);
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-                break;
-            case PIKA_HMAC_SHA1:
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-
-                mbedtls_sha1_init((mbedtls_sha1_context*)context);
-                mbedtls_sha1_starts((mbedtls_sha1_context*)context);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, buff,
-                                    PIKA_HMAC_SHA1);
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-                break;
-            case PIKA_HMAC_SHA256:
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-
-                mbedtls_sha256_init((mbedtls_sha256_context*)context);
-                mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad,
-                                      64);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, buff,
-                                      PIKA_HMAC_SHA256);
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-                break;
-            default:
-                obj_setErrorCode(self, -1);  // not support mode
-                return arg_newNull();  // will not actually return to the python
-                break;
-        }
+        mbedtls_md_context_t* ctx = obj_getStruct(self, "_context");
+        mbedtls_md_hmac_finish(ctx, buff);
         obj_setInt(self, "_digest_flags", flag | 0x01);
-        return arg_newBytes(buff, mode);
+        goto exit;
     }
+exit:
+    return arg_newBytes(buff, obj_getInt(self, "_mode"));
 }
 
 char* _hmac_HMAC_hexdigest(PikaObj* self) {
@@ -235,61 +97,20 @@ char* _hmac_HMAC_hexdigest(PikaObj* self) {
     uint8_t* hexbuff = obj_getBytes(self, "_hexbuff");
     uint8_t flag = obj_getInt(self, "_digest_flags");
 
-    if (flag & 0x01) {  // already digest
-        hmac_to_hex(buff, obj_getInt(self, "mode"), hexbuff);
+    if (flag & 0x01) {                                   // already digest
         obj_setInt(self, "_digest_flags", flag | 0x02);  // set hexdigest flag
-    } else if (flag & 0x02) {                           // already hexdigest
-
+        goto exit;
+    } else if (flag & 0x02) {  // already hexdigest
+        return (char*)hexbuff;
     } else {
-        void* context = obj_getStruct(self, "context");
-        uint8_t* k_opad = obj_getBytes(self, "_k_opad");
-
-        switch (obj_getInt(self, "mode")) {
-            case PIKA_HMAC_MD5:
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-
-                mbedtls_md5_init((mbedtls_md5_context*)context);
-                mbedtls_md5_starts((mbedtls_md5_context*)context);
-                mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64);
-                mbedtls_md5_update((mbedtls_md5_context*)context, buff,
-                                   PIKA_HMAC_MD5);
-                mbedtls_md5_finish((mbedtls_md5_context*)context, buff);
-                mbedtls_md5_free((mbedtls_md5_context*)context);
-                break;
-            case PIKA_HMAC_SHA1:
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-
-                mbedtls_sha1_init((mbedtls_sha1_context*)context);
-                mbedtls_sha1_starts((mbedtls_sha1_context*)context);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64);
-                mbedtls_sha1_update((mbedtls_sha1_context*)context, buff,
-                                    PIKA_HMAC_SHA1);
-                mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff);
-                mbedtls_sha1_free((mbedtls_sha1_context*)context);
-                break;
-            case PIKA_HMAC_SHA256:
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-
-                mbedtls_sha256_init((mbedtls_sha256_context*)context);
-                mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad,
-                                      64);
-                mbedtls_sha256_update((mbedtls_sha256_context*)context, buff,
-                                      PIKA_HMAC_SHA256);
-                mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff);
-                mbedtls_sha256_free((mbedtls_sha256_context*)context);
-                break;
-            default:
-                obj_setErrorCode(self, -1);  // not support mode
-                break;
-        }
-        hmac_to_hex(buff, PIKA_HMAC_MD5, hexbuff);
-        obj_setInt(self, "_digest_flags",
-                   flag | 0x03);  // set digest and hexdigest flags
+        mbedtls_md_context_t* ctx = obj_getStruct(self, "_context");
+        mbedtls_md_hmac_finish(ctx, buff);
+        // set digest and hexdigest flags
+        obj_setInt(self, "_digest_flags", flag | 0x03);
+        goto exit;
     }
+exit:
+    hmac_to_hex(buff, obj_getInt(self, "_mode"), hexbuff);
     return (char*)hexbuff;
 }