int main(int argc, char **argv) { RC2_KEY key; unsigned char t[8]; unsigned char out[40]; int i; for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { RC2_set_key(&key, tests[i].keylen, tests[i].key, tests[i].bitsize); memcpy(t, tests[i].plain, 8); RC2_encryptc(t, t, &key); if (memcmp(t, tests[i].cipher, 8) != 0) { printf("encrypt %d\n", i); exit(1); } RC2_decryptc(t, t, &key); if (memcmp(t, tests[i].plain, 8) != 0) { printf("decrypt: %d\n", i); exit(1); } } /* cbc test */ RC2_set_key(&key, 16, cbc_key, 0); memcpy(t, cbc_iv, 8); RC2_cbc_encrypt(cbc_in_data, out, 32, &key, t, 1); if (memcmp(out_iv, t, 8) != 0) abort(); if (memcmp(out, cbc_out_data, 32) != 0) { printf("cbc test encrypt\n"); exit(1); } memcpy(t, cbc_iv, 8); RC2_cbc_encrypt(out, out, 32, &key, t, 0); if (memcmp(cbc_in_data, out, 32) != 0) { printf("cbc test decrypt \n"); exit(1); } return 0; }
static int rc2_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size) { struct rc2_cbc *k = ctx->cipher_data; RC2_cbc_encrypt(in, out, size, &k->key, ctx->iv, ctx->encrypt); return 1; }
/* {{{ CI_Ceay_Decrypt */ CK_DEFINE_FUNCTION(CK_RV, CI_Ceay_Decrypt)( CK_I_SESSION_DATA_PTR session_data, CK_BYTE_PTR pEncryptedData, /* ciphertext */ CK_ULONG ulEncryptedDataLen, /* ciphertext length */ CK_BYTE_PTR pData, /* gets plaintext */ CK_ULONG_PTR pulDataLen /* gets p-text size */ ) { CK_RV rv; switch(session_data->decrypt_mechanism) { /* {{{ CKM_RSA_PKCS */ case CKM_RSA_PKCS: { CK_BYTE_PTR tmp_buf = NULL_PTR; CK_ULONG key_len; long processed; /* number of bytes processed by the crypto routine */ rv = CKR_OK; CI_LogEntry("C_Decrypt", "RSA PKCS", rv , 0); key_len = CI_Ceay_RSA_size((RSA CK_PTR)session_data->decrypt_state); /* check if this is only a call for the length of the output buffer */ if(pData == NULL_PTR) { *pulDataLen = key_len-CK_I_PKCS1_MIN_PADDING; CI_VarLogEntry("C_Decrypt", "RSA PKCS Datalength calculated (%i)", rv , 0, *pulDataLen); CI_LogEntry("C_Decrypt", "...completed", rv , 0); return CKR_OK; } /* check for length of input */ if(ulEncryptedDataLen != key_len) { rv = CKR_DATA_LEN_RANGE; goto rsa_pkcs1_err; } tmp_buf = CI_ByteStream_new(key_len); processed = RSA_private_decrypt(ulEncryptedDataLen,pEncryptedData, tmp_buf,session_data->decrypt_state, RSA_PKCS1_PADDING); if(processed == -1) { rv = CKR_GENERAL_ERROR; goto rsa_pkcs1_err; } if(*pulDataLen < (unsigned long)processed) { *pulDataLen = processed; rv = CKR_BUFFER_TOO_SMALL; goto rsa_pkcs1_err; } *pulDataLen = processed; memcpy(pData, tmp_buf, processed); rsa_pkcs1_err: if(tmp_buf != NULL_PTR) TC_free(tmp_buf); if(session_data->decrypt_state != NULL_PTR) { RSA_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; } /* }}} */ /* {{{ CKM_RSA_X_509 */ case CKM_RSA_X_509: { CK_BYTE_PTR tmp_buf = NULL_PTR; CK_ULONG key_len; long processed; /* number of bytes processed by the crypto routine */ CI_LogEntry("C_Decrypt", "RSA X509", rv , 0); rv = CKR_OK; key_len = RSA_size((RSA CK_PTR)session_data->decrypt_state); /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto rsa_x509_err; } /* check if this is only a call for the length of the output buffer */ if(pData == NULL_PTR) { *pulDataLen = key_len; rv = CKR_OK; break; } else /* check that buffer is of sufficent size */ { if(*pulDataLen < key_len) { *pulDataLen = key_len; rv = CKR_BUFFER_TOO_SMALL; break; } } /* check for length of input */ if(ulEncryptedDataLen != key_len) { rv = CKR_DATA_LEN_RANGE; goto rsa_x509_err; } tmp_buf = CI_ByteStream_new(key_len); if(tmp_buf == NULL_PTR) { rv = CKR_HOST_MEMORY; goto rsa_x509_err; } processed = RSA_private_decrypt(ulEncryptedDataLen,pEncryptedData, tmp_buf,session_data->decrypt_state, RSA_NO_PADDING); if(processed == -1) { rv = CKR_GENERAL_ERROR; goto rsa_x509_err; } *pulDataLen = processed; memcpy(pData,tmp_buf,key_len); rsa_x509_err: if(tmp_buf != NULL_PTR) TC_free(tmp_buf); if(session_data->decrypt_state != NULL_PTR) { RSA_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; } /* }}} */ /* {{{ CKM_RC4 */ case CKM_RC4: { /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto rc4_err; } /* is this just a test for the length of the recieving buffer? */ rv = CKR_OK; CI_LogEntry("C_Decrypt", "RC4", rv , 0); if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ RC4(session_data->decrypt_state,ulEncryptedDataLen,pEncryptedData,pData); *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; rc4_err: if(session_data->decrypt_state != NULL_PTR) TC_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_RC2_ECB */ case CKM_RC2_ECB: { CK_ULONG count; /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto rc2_cbc_err; } /* RC2 always takes multiples of 8 bytes */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto rc2_ecb_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedDataLen ; count+=8) { RC2_ecb_encrypt(&(pEncryptedData[count]),&(pData[count]), session_data->decrypt_state, RC2_DECRYPT); } *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; rc2_ecb_err: if(session_data->decrypt_state != NULL_PTR) TC_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_RC2_CBC */ case CKM_RC2_CBC: { /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto rc2_cbc_err; } /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto rc2_cbc_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ RC2_cbc_encrypt((unsigned char*)pEncryptedData, (unsigned char*)pData, ulEncryptedDataLen, ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->key, ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->ivec, RC2_DECRYPT); rv = CKR_OK; rc2_cbc_err: CI_RC2_INFO_delete(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_DES_ECB */ case CKM_DES_ECB: { CK_ULONG count; /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto des_ecb_err; } /* DES allways takes multiples of 8 bytes */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto des_ecb_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedDataLen ; count+=8) { des_ecb_encrypt((des_cblock*)(&(pEncryptedData[count])), (des_cblock*)(&(pData[count])), session_data->decrypt_state, DES_DECRYPT); } *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; des_ecb_err: if(session_data->decrypt_state != NULL_PTR) TC_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_DES_CBC */ case CKM_DES_CBC: { /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto des_cbc_err; } /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto des_cbc_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ des_ncbc_encrypt(pEncryptedData, pData, ulEncryptedDataLen, ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), DES_DECRYPT); *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; des_cbc_err: if(session_data->decrypt_state!= NULL_PTR) TC_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_DES_CBC_PAD */ case CKM_DES_CBC_PAD: { CK_BYTE PadValue; CK_ULONG ulPaddingLen, i; /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto des_cbc_pad_err; } /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; break; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; goto des_cbc_pad_err; } /* OK all set. lets compute */ des_ncbc_encrypt(pEncryptedData, pData, ulEncryptedDataLen, ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), DES_DECRYPT); if((CK_BYTE)((pData[ulEncryptedDataLen-1] >= 1 ) && (CK_BYTE)(pData[ulEncryptedDataLen-1] <= 8))) { PadValue = (CK_BYTE)(pData[ulEncryptedDataLen-1]); ulPaddingLen = (CK_ULONG)PadValue; } else { ulPaddingLen = 0; } for (i=0; i<ulPaddingLen; i++) if ((CK_BYTE)(pData[ulEncryptedDataLen-1-i]) != PadValue) { rv = CKR_GENERAL_ERROR; goto des_cbc_pad_err; } *pulDataLen=ulEncryptedDataLen-ulPaddingLen; rv = CKR_OK; des_cbc_pad_err: if(session_data->decrypt_state!= NULL_PTR) TC_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_DES3_ECB */ case CKM_DES3_ECB: { CK_ULONG count; /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto des3_ecb_err; } /* DES always takes multiples of 8 bytes */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto des3_ecb_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedDataLen ; count+=8) { des_ecb3_encrypt((des_cblock*)(&(pEncryptedData[count])), (des_cblock*)(&(pData[count])), ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2], DES_DECRYPT); } *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; des3_ecb_err: if(session_data->decrypt_state!= NULL_PTR) CI_DES3_INFO_delete(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_DES3_CBC */ case CKM_DES3_CBC: { /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto des3_cbc_err; } /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto des3_cbc_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ des_ede3_cbc_encrypt(pEncryptedData, pData, ulEncryptedDataLen, ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->ivec, DES_DECRYPT); *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; des3_cbc_err: if(session_data->decrypt_state != NULL_PTR) CI_DES3_INFO_delete(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_IDEA_ECB */ case CKM_IDEA_ECB: { CK_ULONG count; rv = CKR_OK; CI_LogEntry("C_Decrypt", "IDEA ECB", rv , 0); /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto idea_ecb_err; } /* IDEA always takes multiples of 8 bytes */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto idea_ecb_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* damit wir ne hoffnung haben */ assert(sizeof(CK_BYTE) == sizeof(unsigned char)); /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedDataLen ; count+=8) { /* its the same function for decryption as well, only the key schedule differs */ idea_ecb_encrypt((unsigned char*)&(pEncryptedData[count]), (unsigned char*)&(pData[count]), &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched)); } *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; idea_ecb_err: if(session_data->decrypt_state!= NULL_PTR) TC_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ /* {{{ CKM_IDEA_CBC */ case CKM_IDEA_CBC: { /* terminate operation */ if(pulDataLen == NULL_PTR) { rv = CKR_OK; goto idea_cbc_err; } /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedDataLen%8 != 0) { rv = CKR_DATA_LEN_RANGE; goto idea_cbc_err; } /* is this just a test for the length of the recieving buffer? */ if(pData == NULL_PTR) { *pulDataLen = ulEncryptedDataLen; rv = CKR_OK; break; } /* is the supplied buffer long enough? */ if(*pulDataLen < ulEncryptedDataLen) { *pulDataLen = ulEncryptedDataLen; rv = CKR_BUFFER_TOO_SMALL; break; } /* OK all set. lets compute */ idea_cbc_encrypt((unsigned char*)pEncryptedData, (unsigned char*)pData, ulEncryptedDataLen, &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched), ((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec, IDEA_DECRYPT); *pulDataLen=ulEncryptedDataLen; rv = CKR_OK; if( ((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec != NULL_PTR) TC_free(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec); idea_cbc_err: if(session_data->decrypt_state) TC_free(session_data->decrypt_state); session_data->decrypt_state = NULL_PTR; } break; /* }}} */ default: rv = CKR_MECHANISM_INVALID; CI_VarLogEntry("C_Decrypt", "algorithm specified: %s", rv, 0, CI_MechanismStr(session_data->decrypt_mechanism)); } CI_LogEntry("C_Decrypt", "...completed", rv , 0); return rv; }
/* {{{ CI_Ceay_DecryptUpdate */ CK_DEFINE_FUNCTION(CK_RV, CI_Ceay_DecryptUpdate)( CK_I_SESSION_DATA_PTR session_data, CK_BYTE_PTR pEncryptedPart, /* encrypted data */ CK_ULONG ulEncryptedPartLen, /* input length */ CK_BYTE_PTR pPart, /* gets plaintext */ CK_ULONG_PTR pulPartLen /* p-text size */ ) { CK_RV rv; switch(session_data->decrypt_mechanism) { /* {{{ CKM_RC4 */ case CKM_RC4: { rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "RC4", rv , 0); /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ RC4(session_data->decrypt_state,ulEncryptedPartLen,pEncryptedPart,pPart); *pulPartLen=ulEncryptedPartLen; } break; /* }}} */ /* {{{ CKM_RC2_ECB */ case CKM_RC2_ECB: { CK_ULONG count; rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "RC2 ECB", rv , 0); /* RC2 always takes multiples of 8 bytes */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedPartLen ; count+=8) { RC2_ecb_encrypt(&(pEncryptedPart[count]), &(pPart[count]), session_data->decrypt_state, RC2_DECRYPT); } *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_RC2_CBC */ case CKM_RC2_CBC: { rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "RC2 CBC", rv , 0); /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ RC2_cbc_encrypt((unsigned char*)pEncryptedPart, (unsigned char*)pPart, ulEncryptedPartLen, ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->key, ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->ivec, RC2_DECRYPT); *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_DES_ECB */ case CKM_DES_ECB: { CK_ULONG count; rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "DES ECB", rv , 0); /* DES always takes multiples of 8 bytes */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedPartLen ; count+=8) { des_ecb_encrypt((des_cblock*)(&(pEncryptedPart[count])), (des_cblock*)(&(pPart[count])), session_data->decrypt_state, DES_DECRYPT); } *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_DES_CBC */ case CKM_DES_CBC: { rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "DES3 CBC", rv , 0); /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ des_ncbc_encrypt(pEncryptedPart, pPart, ulEncryptedPartLen, ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), DES_DECRYPT); *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_DES_CBC_PAD */ case CKM_DES_CBC_PAD: { CK_BYTE_PTR ptmpbuf = NULL_PTR; /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ ptmpbuf = CI_ByteStream_new(ulEncryptedPartLen); if(ptmpbuf == NULL_PTR) return CKR_HOST_MEMORY; if(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->pad) { memcpy(ptmpbuf, ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->lastblock, 8); memcpy(ptmpbuf+8, pEncryptedPart, ulEncryptedPartLen-8); *pulPartLen = ulEncryptedPartLen; } else { memcpy(ptmpbuf, pEncryptedPart, ulEncryptedPartLen-8); *pulPartLen = ulEncryptedPartLen-8; ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->pad = 8; } des_ncbc_encrypt(ptmpbuf, pPart, *pulPartLen, ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), DES_DECRYPT); memcpy(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->lastblock, pEncryptedPart+ulEncryptedPartLen-8, 8); TC_free(ptmpbuf); rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_DES3_ECB */ case CKM_DES3_ECB: { CK_ULONG count; /* DES always takes multiples of 8 bytes */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedPartLen ; count+=8) { des_ecb3_encrypt((des_cblock*)(&(pPart[count])), (des_cblock*)(&(pEncryptedPart[count])), ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2], DES_DECRYPT); } *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_DES3_CBC */ case CKM_DES3_CBC: { rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "IDEA CBC", rv , 0); /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ des_ede3_cbc_encrypt(pEncryptedPart, pPart, ulEncryptedPartLen, ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2], ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->ivec, DES_DECRYPT); *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_IDEA_ECB */ case CKM_IDEA_ECB: { CK_ULONG count; rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "IDEA ECB", rv , 0); /* DES always takes multiples of 8 bytes */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* damit wir ne hoffnung haben */ assert(sizeof(CK_BYTE) == sizeof(unsigned char)); /* OK all set. lets compute */ /* in blocks of 8 bytes. */ for(count=0; count<ulEncryptedPartLen ; count+=8) { /* its the same function for decryption as well, only the key schedule differs */ idea_ecb_encrypt((unsigned char*)&(pEncryptedPart[count]), (unsigned char*)&(pPart[count]), &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched)); } *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ /* {{{ CKM_IDEA_CBC */ case CKM_IDEA_CBC: { rv = CKR_OK; CI_LogEntry("C_DecryptUpdate", "IDEA CBC", rv , 0); /* is the length of the supplied data a multiple of 8 to create des-blocks? */ if(ulEncryptedPartLen%8 != 0) return CKR_DATA_LEN_RANGE; /* is this just a test for the length of the recieving buffer? */ if(pPart == NULL_PTR) { *pulPartLen = ulEncryptedPartLen; return CKR_OK; } /* is the supplied buffer long enough? */ if(*pulPartLen < ulEncryptedPartLen) { *pulPartLen = ulEncryptedPartLen; return CKR_BUFFER_TOO_SMALL; } /* OK all set. lets compute */ idea_cbc_encrypt((unsigned char*)pEncryptedPart, (unsigned char*)pPart, ulEncryptedPartLen, &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched), ((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec, IDEA_DECRYPT); *pulPartLen=ulEncryptedPartLen; rv = CKR_OK; } break; /* }}} */ default: rv = CKR_MECHANISM_INVALID; CI_VarLogEntry("C_DecryptUpdate", "algorithm specified: %s", rv, 0, CI_MechanismStr(session_data->decrypt_mechanism)); } CI_VarLogEntry("C_DecryptUpdate", "decryption (%s) result: %s", rv, 2, CI_MechanismStr(session_data->decrypt_mechanism), CI_PrintableByteStream(pPart,*pulPartLen)); CI_LogEntry("C_DecryptUpdate", "...completed", rv , 0); return rv; }
int main(int argc, char **argv) { long count; static unsigned char buf[BUFSIZE]; static unsigned char key[] ={ 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, }; RC2_KEY sch; double a,b,c,d; #ifndef SIGALRM long ca,cb,cc; #endif #ifndef TIMES printf("To get the most accurate results, try to run this\n"); printf("program when this computer is idle.\n"); #endif #ifndef SIGALRM printf("First we calculate the approximate speed ...\n"); RC2_set_key(&sch,16,key,128); count=10; do { long i; unsigned long data[2]; count*=2; Time_F(START); for (i=count; i; i--) RC2_encrypt(data,&sch); d=Time_F(STOP); } while (d < 3.0); ca=count/512; cb=count; cc=count*8/BUFSIZE+1; printf("Doing RC2_set_key %ld times\n",ca); #define COND(d) (count != (d)) #define COUNT(d) (d) #else #define COND(c) (run) #define COUNT(d) (count) signal(SIGALRM,sig_done); printf("Doing RC2_set_key for 10 seconds\n"); alarm(10); #endif Time_F(START); for (count=0,run=1; COND(ca); count+=4) { RC2_set_key(&sch,16,key,128); RC2_set_key(&sch,16,key,128); RC2_set_key(&sch,16,key,128); RC2_set_key(&sch,16,key,128); } d=Time_F(STOP); printf("%ld RC2_set_key's in %.2f seconds\n",count,d); a=((double)COUNT(ca))/d; #ifdef SIGALRM printf("Doing RC2_encrypt's for 10 seconds\n"); alarm(10); #else printf("Doing RC2_encrypt %ld times\n",cb); #endif Time_F(START); for (count=0,run=1; COND(cb); count+=4) { unsigned long data[2]; RC2_encrypt(data,&sch); RC2_encrypt(data,&sch); RC2_encrypt(data,&sch); RC2_encrypt(data,&sch); } d=Time_F(STOP); printf("%ld RC2_encrypt's in %.2f second\n",count,d); b=((double)COUNT(cb)*8)/d; #ifdef SIGALRM printf("Doing RC2_cbc_encrypt on %ld byte blocks for 10 seconds\n", BUFSIZE); alarm(10); #else printf("Doing RC2_cbc_encrypt %ld times on %ld byte blocks\n",cc, BUFSIZE); #endif Time_F(START); for (count=0,run=1; COND(cc); count++) RC2_cbc_encrypt(buf,buf,BUFSIZE,&sch, &(key[0]),RC2_ENCRYPT); d=Time_F(STOP); printf("%ld RC2_cbc_encrypt's of %ld byte blocks in %.2f second\n", count,BUFSIZE,d); c=((double)COUNT(cc)*BUFSIZE)/d; printf("RC2 set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a); printf("RC2 raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b); printf("RC2 cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c); exit(0); #if defined(LINT) || defined(OPENSSL_SYS_MSDOS) return(0); #endif }
int main(void) { int i; RC2_KEY key; BIO* bio_out; unsigned char const iv_data[RC2_BLOCK] = { 0xcc, 0xfe, 0xcd, 0x3e, 0x21, 0xde, 0x1c, 0x31 }; static unsigned const char RC2Key[RC2_KEY_LENGTH] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, }; unsigned char iv[RC2_BLOCK]; char* data = "The worthwhile problems are the ones you can" "really solve or help solve, the ones you can" "really contribute something to. No " "problem is too small or too trivial if we " "can really do something about it." "- Richard Feynman"; /* Round up the length to the higher multiple of 8 */ int length = (strlen(data) + (RC2_BLOCK - 1)) & ~(RC2_BLOCK - 1); /* Input pointer to OpenSSL's RC2 CBC method must be a multiple of 8. */ /* Hence, use the length calcualted above and fill the extra bytes with 0's */ char* data_to_encrypt = (char*) calloc(length, sizeof(char)); /* Output pointer to OpenSSL's RC2 CBC method must be a multiple of 8. */ /* Hence, use the length calcualted above. */ char* ciphertext = (char*) malloc(sizeof(char) * length); char* plaintext = (char*) malloc(sizeof(char) * length); /* Copy the IV data to the IV array. The IV array will be updated by the RC2_cbc_encrypt call */ memcpy(iv, iv_data, RC2_BLOCK); /* Copy the data to the padded array created earlier */ memcpy(data_to_encrypt, data, strlen(data)); /* set the key structure using the (unmodified) predefined key */ RC2_set_key(&key, RC2_KEY_LENGTH, RC2Key, 1024); RC2_cbc_encrypt(data_to_encrypt, ciphertext, length, &key, iv, RC2_ENCRYPT); bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); BIO_printf(bio_out, "Original plaintext: %s\n\n", data_to_encrypt); BIO_printf(bio_out, "Ciphertext: "); /* print out the ciphertext */ for (i = 0; i < length; i++) BIO_printf(bio_out, "%02x", ((unsigned char*)ciphertext)[i]); BIO_printf(bio_out, "\n\n"); /* Copy the original IV data back to the IV array - as it was overwritten during the encryption process */ memcpy(iv, iv_data, RC2_BLOCK); /* start the decryption process */ RC2_cbc_encrypt(ciphertext, plaintext, length, &key, iv, RC2_DECRYPT); BIO_printf(bio_out, "Recovered plaintext: "); /* print out the plaintext */ for (i = 0; i < length; i++) BIO_printf(bio_out, "%c", ((unsigned char*)plaintext)[i]); BIO_printf(bio_out, "\n\n"); BIO_free(bio_out); free(data_to_encrypt); free(ciphertext); free(plaintext); return 0; }