1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * RC2 low level APIs are deprecated for public use, but still ok for internal 12e1051a39Sopenharmony_ci * use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <stdio.h> 17e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_RC2 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci# include <openssl/evp.h> 22e1051a39Sopenharmony_ci# include <openssl/objects.h> 23e1051a39Sopenharmony_ci# include "crypto/evp.h" 24e1051a39Sopenharmony_ci# include <openssl/rc2.h> 25e1051a39Sopenharmony_ci# include "evp_local.h" 26e1051a39Sopenharmony_ci 27e1051a39Sopenharmony_cistatic int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 28e1051a39Sopenharmony_ci const unsigned char *iv, int enc); 29e1051a39Sopenharmony_cistatic int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); 30e1051a39Sopenharmony_cistatic int rc2_magic_to_meth(int i); 31e1051a39Sopenharmony_cistatic int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); 32e1051a39Sopenharmony_cistatic int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); 33e1051a39Sopenharmony_cistatic int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_citypedef struct { 36e1051a39Sopenharmony_ci int key_bits; /* effective key bits */ 37e1051a39Sopenharmony_ci RC2_KEY ks; /* key schedule */ 38e1051a39Sopenharmony_ci} EVP_RC2_KEY; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci# define data(ctx) EVP_C_DATA(EVP_RC2_KEY,ctx) 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ciIMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2, 43e1051a39Sopenharmony_ci 8, 44e1051a39Sopenharmony_ci RC2_KEY_LENGTH, 8, 64, 45e1051a39Sopenharmony_ci EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, 46e1051a39Sopenharmony_ci rc2_init_key, NULL, 47e1051a39Sopenharmony_ci rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, 48e1051a39Sopenharmony_ci rc2_ctrl) 49e1051a39Sopenharmony_ci# define RC2_40_MAGIC 0xa0 50e1051a39Sopenharmony_ci# define RC2_64_MAGIC 0x78 51e1051a39Sopenharmony_ci# define RC2_128_MAGIC 0x3a 52e1051a39Sopenharmony_cistatic const EVP_CIPHER r2_64_cbc_cipher = { 53e1051a39Sopenharmony_ci NID_rc2_64_cbc, 54e1051a39Sopenharmony_ci 8, 8 /* 64 bit */ , 8, 55e1051a39Sopenharmony_ci EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, 56e1051a39Sopenharmony_ci EVP_ORIG_GLOBAL, 57e1051a39Sopenharmony_ci rc2_init_key, 58e1051a39Sopenharmony_ci rc2_cbc_cipher, 59e1051a39Sopenharmony_ci NULL, 60e1051a39Sopenharmony_ci sizeof(EVP_RC2_KEY), 61e1051a39Sopenharmony_ci rc2_set_asn1_type_and_iv, 62e1051a39Sopenharmony_ci rc2_get_asn1_type_and_iv, 63e1051a39Sopenharmony_ci rc2_ctrl, 64e1051a39Sopenharmony_ci NULL 65e1051a39Sopenharmony_ci}; 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_cistatic const EVP_CIPHER r2_40_cbc_cipher = { 68e1051a39Sopenharmony_ci NID_rc2_40_cbc, 69e1051a39Sopenharmony_ci 8, 5 /* 40 bit */ , 8, 70e1051a39Sopenharmony_ci EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, 71e1051a39Sopenharmony_ci EVP_ORIG_GLOBAL, 72e1051a39Sopenharmony_ci rc2_init_key, 73e1051a39Sopenharmony_ci rc2_cbc_cipher, 74e1051a39Sopenharmony_ci NULL, 75e1051a39Sopenharmony_ci sizeof(EVP_RC2_KEY), 76e1051a39Sopenharmony_ci rc2_set_asn1_type_and_iv, 77e1051a39Sopenharmony_ci rc2_get_asn1_type_and_iv, 78e1051a39Sopenharmony_ci rc2_ctrl, 79e1051a39Sopenharmony_ci NULL 80e1051a39Sopenharmony_ci}; 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ciconst EVP_CIPHER *EVP_rc2_64_cbc(void) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci return &r2_64_cbc_cipher; 85e1051a39Sopenharmony_ci} 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_ciconst EVP_CIPHER *EVP_rc2_40_cbc(void) 88e1051a39Sopenharmony_ci{ 89e1051a39Sopenharmony_ci return &r2_40_cbc_cipher; 90e1051a39Sopenharmony_ci} 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_cistatic int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 93e1051a39Sopenharmony_ci const unsigned char *iv, int enc) 94e1051a39Sopenharmony_ci{ 95e1051a39Sopenharmony_ci RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_get_key_length(ctx), 96e1051a39Sopenharmony_ci key, data(ctx)->key_bits); 97e1051a39Sopenharmony_ci return 1; 98e1051a39Sopenharmony_ci} 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_cistatic int rc2_meth_to_magic(EVP_CIPHER_CTX *e) 101e1051a39Sopenharmony_ci{ 102e1051a39Sopenharmony_ci int i; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i) <= 0) 105e1051a39Sopenharmony_ci return 0; 106e1051a39Sopenharmony_ci if (i == 128) 107e1051a39Sopenharmony_ci return RC2_128_MAGIC; 108e1051a39Sopenharmony_ci else if (i == 64) 109e1051a39Sopenharmony_ci return RC2_64_MAGIC; 110e1051a39Sopenharmony_ci else if (i == 40) 111e1051a39Sopenharmony_ci return RC2_40_MAGIC; 112e1051a39Sopenharmony_ci else 113e1051a39Sopenharmony_ci return 0; 114e1051a39Sopenharmony_ci} 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_cistatic int rc2_magic_to_meth(int i) 117e1051a39Sopenharmony_ci{ 118e1051a39Sopenharmony_ci if (i == RC2_128_MAGIC) 119e1051a39Sopenharmony_ci return 128; 120e1051a39Sopenharmony_ci else if (i == RC2_64_MAGIC) 121e1051a39Sopenharmony_ci return 64; 122e1051a39Sopenharmony_ci else if (i == RC2_40_MAGIC) 123e1051a39Sopenharmony_ci return 40; 124e1051a39Sopenharmony_ci else { 125e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE); 126e1051a39Sopenharmony_ci return 0; 127e1051a39Sopenharmony_ci } 128e1051a39Sopenharmony_ci} 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_cistatic int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 131e1051a39Sopenharmony_ci{ 132e1051a39Sopenharmony_ci long num = 0; 133e1051a39Sopenharmony_ci int i = 0; 134e1051a39Sopenharmony_ci int key_bits; 135e1051a39Sopenharmony_ci unsigned int l; 136e1051a39Sopenharmony_ci unsigned char iv[EVP_MAX_IV_LENGTH]; 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci if (type != NULL) { 139e1051a39Sopenharmony_ci l = EVP_CIPHER_CTX_get_iv_length(c); 140e1051a39Sopenharmony_ci OPENSSL_assert(l <= sizeof(iv)); 141e1051a39Sopenharmony_ci i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); 142e1051a39Sopenharmony_ci if (i != (int)l) 143e1051a39Sopenharmony_ci return -1; 144e1051a39Sopenharmony_ci key_bits = rc2_magic_to_meth((int)num); 145e1051a39Sopenharmony_ci if (!key_bits) 146e1051a39Sopenharmony_ci return -1; 147e1051a39Sopenharmony_ci if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) 148e1051a39Sopenharmony_ci return -1; 149e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, 150e1051a39Sopenharmony_ci NULL) <= 0 151e1051a39Sopenharmony_ci || EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0) 152e1051a39Sopenharmony_ci return -1; 153e1051a39Sopenharmony_ci } 154e1051a39Sopenharmony_ci return i; 155e1051a39Sopenharmony_ci} 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_cistatic int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 158e1051a39Sopenharmony_ci{ 159e1051a39Sopenharmony_ci long num; 160e1051a39Sopenharmony_ci int i = 0, j; 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ci if (type != NULL) { 163e1051a39Sopenharmony_ci num = rc2_meth_to_magic(c); 164e1051a39Sopenharmony_ci j = EVP_CIPHER_CTX_get_iv_length(c); 165e1051a39Sopenharmony_ci i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); 166e1051a39Sopenharmony_ci } 167e1051a39Sopenharmony_ci return i; 168e1051a39Sopenharmony_ci} 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_cistatic int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 171e1051a39Sopenharmony_ci{ 172e1051a39Sopenharmony_ci switch (type) { 173e1051a39Sopenharmony_ci case EVP_CTRL_INIT: 174e1051a39Sopenharmony_ci data(c)->key_bits = EVP_CIPHER_CTX_get_key_length(c) * 8; 175e1051a39Sopenharmony_ci return 1; 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ci case EVP_CTRL_GET_RC2_KEY_BITS: 178e1051a39Sopenharmony_ci *(int *)ptr = data(c)->key_bits; 179e1051a39Sopenharmony_ci return 1; 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci case EVP_CTRL_SET_RC2_KEY_BITS: 182e1051a39Sopenharmony_ci if (arg > 0) { 183e1051a39Sopenharmony_ci data(c)->key_bits = arg; 184e1051a39Sopenharmony_ci return 1; 185e1051a39Sopenharmony_ci } 186e1051a39Sopenharmony_ci return 0; 187e1051a39Sopenharmony_ci# ifdef PBE_PRF_TEST 188e1051a39Sopenharmony_ci case EVP_CTRL_PBE_PRF_NID: 189e1051a39Sopenharmony_ci *(int *)ptr = NID_hmacWithMD5; 190e1051a39Sopenharmony_ci return 1; 191e1051a39Sopenharmony_ci# endif 192e1051a39Sopenharmony_ci 193e1051a39Sopenharmony_ci default: 194e1051a39Sopenharmony_ci return -1; 195e1051a39Sopenharmony_ci } 196e1051a39Sopenharmony_ci} 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_ci#endif 199