static int sms4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { int mode; mode = ctx->cipher->flags & EVP_CIPH_MODE; if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { ret = sms4_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data); sms4->block = (block128_f)sms4_decrypt; sms4->stream.cbc = (mode == EVP_CIPH_CBC_MODE ? (cbc128_f)sms4_cbc_encrypt : NULL); } else { ret = sms4_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data); sms4->block = (block128_f)sms4_encrypt; if (mode == EVP_CIPH_CBC_MODE) { sms4->stream.cbc = (cbc128_f)sms4_cbc_encrypt; } else if (mode == EVP_CIPH_CTR_MODE) { sms4->stream.ctr = (ctr128_f)sms4_ctr32_encrypt_blocks; } else { sms4->stream.cbc = NULL; } } if (ret < 0) { return 0; } return 1; }
static int sms4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { if(!enc) { if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) enc = 1; else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) enc = 1; //encrypt key == decrypt key } if (enc) sms4_set_encrypt_key(ctx->cipher_data, key); else //ecb, cbc sms4_set_decrypt_key(ctx->cipher_data, key); return 1; }
static int sms4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { int mode; EVP_SMS4_KEY *dat = EVP_C_DATA(EVP_SMS4_KEY, ctx); mode = EVP_CIPHER_CTX_mode(ctx); if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { sms4_set_decrypt_key(&dat->ks, key); } else { sms4_set_encrypt_key(&dat->ks, key); } dat->block = (block128_f)sms4_encrypt; dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? (cbc128_f) sms4_cbc_encrypt : NULL; return 1; }
static int sms4_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { EVP_SMS4_WRAP_CTX *wctx = EVP_C_DATA(EVP_SMS4_WRAP_CTX,ctx); if (!iv && !key) return 1; if (key) { if (EVP_CIPHER_CTX_encrypting(ctx)) sms4_set_encrypt_key(&wctx->ks.ks, key); else sms4_set_decrypt_key(&wctx->ks.ks, key); if (!iv) wctx->iv = NULL; } if (iv) { memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, EVP_CIPHER_CTX_iv_length(ctx)); wctx->iv = EVP_CIPHER_CTX_iv_noconst(ctx); } return 1; }
// 解密 unsigned char SMS4_Decryption(unsigned char *key, unsigned char *ciphertext, unsigned short ciphertextlen, unsigned char *plaintext, unsigned short *plaintextlen, unsigned char *IV) { assert(key && ciphertext && plaintext && plaintextlen && IV); sms4_key_t pkey; sms4_set_decrypt_key(&pkey, key); sms4_cbc_encrypt(ciphertext, ciphertext, ciphertextlen, &pkey, IV, 0); int pad = ciphertext[ciphertextlen - 1]; for (int i = 1; i <= pad; ++ i) { if (ciphertext[ciphertextlen - i] != pad) return 1; // 补齐出错 } *plaintextlen = ciphertextlen - pad; memcpy(plaintext, ciphertext, *plaintextlen); return 0; }