1*e71b7053SJung-uk Kim /* 2*e71b7053SJung-uk Kim * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3ddd58736SKris Kennaway * 4*e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5*e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6*e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7*e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 8ddd58736SKris Kennaway */ 9ddd58736SKris Kennaway 10ddd58736SKris Kennaway #include <stdio.h> 11*e71b7053SJung-uk Kim #include "internal/cryptlib.h" 123b4e3dcbSSimon L. B. Nielsen 133b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_RC2 143b4e3dcbSSimon L. B. Nielsen 15ddd58736SKris Kennaway # include <openssl/evp.h> 16ddd58736SKris Kennaway # include <openssl/objects.h> 17*e71b7053SJung-uk Kim # include "internal/evp_int.h" 185c87c606SMark Murray # include <openssl/rc2.h> 19ddd58736SKris Kennaway 20ddd58736SKris Kennaway static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 21ddd58736SKris Kennaway const unsigned char *iv, int enc); 22ddd58736SKris Kennaway static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); 23ddd58736SKris Kennaway static int rc2_magic_to_meth(int i); 24ddd58736SKris Kennaway static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); 25ddd58736SKris Kennaway static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); 26ddd58736SKris Kennaway static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); 27ddd58736SKris Kennaway 286f9291ceSJung-uk Kim typedef struct { 295c87c606SMark Murray int key_bits; /* effective key bits */ 305c87c606SMark Murray RC2_KEY ks; /* key schedule */ 315c87c606SMark Murray } EVP_RC2_KEY; 325c87c606SMark Murray 33*e71b7053SJung-uk Kim # define data(ctx) EVP_C_DATA(EVP_RC2_KEY,ctx) 345c87c606SMark Murray 355c87c606SMark Murray IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2, 36ddd58736SKris Kennaway 8, 375c87c606SMark Murray RC2_KEY_LENGTH, 8, 64, 38ddd58736SKris Kennaway EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, 39ddd58736SKris Kennaway rc2_init_key, NULL, 40ddd58736SKris Kennaway rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, 41ddd58736SKris Kennaway rc2_ctrl) 42ddd58736SKris Kennaway # define RC2_40_MAGIC 0xa0 43ddd58736SKris Kennaway # define RC2_64_MAGIC 0x78 44ddd58736SKris Kennaway # define RC2_128_MAGIC 0x3a 456f9291ceSJung-uk Kim static const EVP_CIPHER r2_64_cbc_cipher = { 46ddd58736SKris Kennaway NID_rc2_64_cbc, 47ddd58736SKris Kennaway 8, 8 /* 64 bit */ , 8, 48ddd58736SKris Kennaway EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, 49ddd58736SKris Kennaway rc2_init_key, 50ddd58736SKris Kennaway rc2_cbc_cipher, 51ddd58736SKris Kennaway NULL, 525c87c606SMark Murray sizeof(EVP_RC2_KEY), 53ddd58736SKris Kennaway rc2_set_asn1_type_and_iv, 54ddd58736SKris Kennaway rc2_get_asn1_type_and_iv, 55ddd58736SKris Kennaway rc2_ctrl, 56ddd58736SKris Kennaway NULL 57ddd58736SKris Kennaway }; 58ddd58736SKris Kennaway 596f9291ceSJung-uk Kim static const EVP_CIPHER r2_40_cbc_cipher = { 60ddd58736SKris Kennaway NID_rc2_40_cbc, 61ddd58736SKris Kennaway 8, 5 /* 40 bit */ , 8, 62ddd58736SKris Kennaway EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, 63ddd58736SKris Kennaway rc2_init_key, 64ddd58736SKris Kennaway rc2_cbc_cipher, 65ddd58736SKris Kennaway NULL, 665c87c606SMark Murray sizeof(EVP_RC2_KEY), 67ddd58736SKris Kennaway rc2_set_asn1_type_and_iv, 68ddd58736SKris Kennaway rc2_get_asn1_type_and_iv, 69ddd58736SKris Kennaway rc2_ctrl, 70ddd58736SKris Kennaway NULL 71ddd58736SKris Kennaway }; 72ddd58736SKris Kennaway 735c87c606SMark Murray const EVP_CIPHER *EVP_rc2_64_cbc(void) 74ddd58736SKris Kennaway { 75*e71b7053SJung-uk Kim return &r2_64_cbc_cipher; 76ddd58736SKris Kennaway } 77ddd58736SKris Kennaway 785c87c606SMark Murray const EVP_CIPHER *EVP_rc2_40_cbc(void) 79ddd58736SKris Kennaway { 80*e71b7053SJung-uk Kim return &r2_40_cbc_cipher; 81ddd58736SKris Kennaway } 82ddd58736SKris Kennaway 83ddd58736SKris Kennaway static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 84ddd58736SKris Kennaway const unsigned char *iv, int enc) 85ddd58736SKris Kennaway { 865c87c606SMark Murray RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), 875c87c606SMark Murray key, data(ctx)->key_bits); 88ddd58736SKris Kennaway return 1; 89ddd58736SKris Kennaway } 90ddd58736SKris Kennaway 91ddd58736SKris Kennaway static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) 92ddd58736SKris Kennaway { 93ddd58736SKris Kennaway int i; 94ddd58736SKris Kennaway 95ddd58736SKris Kennaway EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i); 966f9291ceSJung-uk Kim if (i == 128) 97*e71b7053SJung-uk Kim return RC2_128_MAGIC; 986f9291ceSJung-uk Kim else if (i == 64) 99*e71b7053SJung-uk Kim return RC2_64_MAGIC; 1006f9291ceSJung-uk Kim else if (i == 40) 101*e71b7053SJung-uk Kim return RC2_40_MAGIC; 1026f9291ceSJung-uk Kim else 103*e71b7053SJung-uk Kim return 0; 104ddd58736SKris Kennaway } 105ddd58736SKris Kennaway 106ddd58736SKris Kennaway static int rc2_magic_to_meth(int i) 107ddd58736SKris Kennaway { 1086f9291ceSJung-uk Kim if (i == RC2_128_MAGIC) 1096f9291ceSJung-uk Kim return 128; 1106f9291ceSJung-uk Kim else if (i == RC2_64_MAGIC) 1116f9291ceSJung-uk Kim return 64; 1126f9291ceSJung-uk Kim else if (i == RC2_40_MAGIC) 1136f9291ceSJung-uk Kim return 40; 1146f9291ceSJung-uk Kim else { 115ddd58736SKris Kennaway EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE); 116*e71b7053SJung-uk Kim return 0; 117ddd58736SKris Kennaway } 118ddd58736SKris Kennaway } 119ddd58736SKris Kennaway 120ddd58736SKris Kennaway static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 121ddd58736SKris Kennaway { 122ddd58736SKris Kennaway long num = 0; 1233b4e3dcbSSimon L. B. Nielsen int i = 0; 124ddd58736SKris Kennaway int key_bits; 1253b4e3dcbSSimon L. B. Nielsen unsigned int l; 126ddd58736SKris Kennaway unsigned char iv[EVP_MAX_IV_LENGTH]; 127ddd58736SKris Kennaway 1286f9291ceSJung-uk Kim if (type != NULL) { 129ddd58736SKris Kennaway l = EVP_CIPHER_CTX_iv_length(c); 1303b4e3dcbSSimon L. B. Nielsen OPENSSL_assert(l <= sizeof(iv)); 131ddd58736SKris Kennaway i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); 1323b4e3dcbSSimon L. B. Nielsen if (i != (int)l) 133*e71b7053SJung-uk Kim return -1; 134ddd58736SKris Kennaway key_bits = rc2_magic_to_meth((int)num); 135ddd58736SKris Kennaway if (!key_bits) 136*e71b7053SJung-uk Kim return -1; 1371f13597dSJung-uk Kim if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) 1381f13597dSJung-uk Kim return -1; 139ddd58736SKris Kennaway EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); 140*e71b7053SJung-uk Kim if (EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0) 141*e71b7053SJung-uk Kim return -1; 142ddd58736SKris Kennaway } 143*e71b7053SJung-uk Kim return i; 144ddd58736SKris Kennaway } 145ddd58736SKris Kennaway 146ddd58736SKris Kennaway static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 147ddd58736SKris Kennaway { 148ddd58736SKris Kennaway long num; 149ddd58736SKris Kennaway int i = 0, j; 150ddd58736SKris Kennaway 1516f9291ceSJung-uk Kim if (type != NULL) { 152ddd58736SKris Kennaway num = rc2_meth_to_magic(c); 153ddd58736SKris Kennaway j = EVP_CIPHER_CTX_iv_length(c); 154*e71b7053SJung-uk Kim i = ASN1_TYPE_set_int_octetstring(type, num, 155*e71b7053SJung-uk Kim (unsigned char *)EVP_CIPHER_CTX_original_iv(c), 156*e71b7053SJung-uk Kim j); 157ddd58736SKris Kennaway } 158*e71b7053SJung-uk Kim return i; 159ddd58736SKris Kennaway } 160ddd58736SKris Kennaway 161ddd58736SKris Kennaway static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 162ddd58736SKris Kennaway { 1636f9291ceSJung-uk Kim switch (type) { 164ddd58736SKris Kennaway case EVP_CTRL_INIT: 1655c87c606SMark Murray data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8; 166ddd58736SKris Kennaway return 1; 167ddd58736SKris Kennaway 168ddd58736SKris Kennaway case EVP_CTRL_GET_RC2_KEY_BITS: 1695c87c606SMark Murray *(int *)ptr = data(c)->key_bits; 170ddd58736SKris Kennaway return 1; 171ddd58736SKris Kennaway 172ddd58736SKris Kennaway case EVP_CTRL_SET_RC2_KEY_BITS: 1736f9291ceSJung-uk Kim if (arg > 0) { 1745c87c606SMark Murray data(c)->key_bits = arg; 175ddd58736SKris Kennaway return 1; 176ddd58736SKris Kennaway } 177ddd58736SKris Kennaway return 0; 1781f13597dSJung-uk Kim # ifdef PBE_PRF_TEST 1791f13597dSJung-uk Kim case EVP_CTRL_PBE_PRF_NID: 1801f13597dSJung-uk Kim *(int *)ptr = NID_hmacWithMD5; 1811f13597dSJung-uk Kim return 1; 1821f13597dSJung-uk Kim # endif 183ddd58736SKris Kennaway 184ddd58736SKris Kennaway default: 185ddd58736SKris Kennaway return -1; 186ddd58736SKris Kennaway } 187ddd58736SKris Kennaway } 188ddd58736SKris Kennaway 189ddd58736SKris Kennaway #endif 190