int cryDes3UtilDecrypt(const char *sInBuf, int iInLen, char *sOutBuf, int *piOutLen, const char sKey[24]) { des3_context tCtx; if (*piOutLen < (iInLen / 8 + (iInLen % 8 == 0 ? 0 : 1)) * 8) return -1; des3_set3key_dec(&tCtx, (unsigned char *)sKey); *piOutLen = 0; while (iInLen > 0) { if (iInLen >= 8) des3_crypt_ecb(&tCtx, (unsigned char *)sInBuf + *piOutLen, (unsigned char *)sOutBuf + *piOutLen); else { memcpy(sOutBuf + *piOutLen, sInBuf + *piOutLen, iInLen); memset(sOutBuf + *piOutLen + iInLen, 0, 8 - iInLen); des3_crypt_ecb(&tCtx, (unsigned char *)sOutBuf + *piOutLen, (unsigned char *)sOutBuf + *piOutLen); } *piOutLen += 8; iInLen = iInLen > 8 ? iInLen - 8 : 0; } return 0; }
static mrb_value mrb_des3_decrypt(mrb_state *mrb, mrb_value self) { mrb_value mode, key, source, dest, iv; unsigned char output[100]; des3_context ctx; mrb_int len=16; memset(output, 0, sizeof(output)); mrb_get_args(mrb, "SSSS", &mode, &key, &source, &iv); des3_init(&ctx); if (RSTRING_LEN(key) == 16) { des3_set2key_dec(&ctx, RSTRING_PTR(key)); } else if (RSTRING_LEN(key) == 24) { des3_set3key_dec(&ctx, RSTRING_PTR(key)); } else { des3_free(&ctx); return mrb_nil_value(); } if (mrb_str_cmp(mrb, mode, mrb_str_new(mrb, "CBC", 3)) == 0) { des3_crypt_cbc(&ctx, DES_DECRYPT, RSTRING_LEN(source), RSTRING_PTR(iv), RSTRING_PTR(source), output); len = RSTRING_LEN(source); } else if (mrb_str_cmp(mrb, mode, mrb_str_new(mrb, "ECB", 3)) == 0) { des3_crypt_ecb(&ctx, RSTRING_PTR(source), output); len = 8; } else { des3_free(&ctx); return mrb_nil_value(); } des3_free(&ctx); return mrb_str_new(mrb, output, len); }
static int des3_crypt_ecb_wrap( void *ctx, operation_t operation, const unsigned char *input, unsigned char *output ) { ((void) operation); return des3_crypt_ecb( (des3_context *) ctx, input, output ); }