Files
m241Neelima/components/ip_net2-6.9/ipcrypto/src/ipcrypto_rsa_oaep.c
T
2026-07-30 11:19:44 +05:30

169 lines
5.0 KiB
C

#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcrypto_config.h>
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_err.h>
#include <openssl/evp.h>
/*
*===========================================================================
* ipcrypto_oaep_mask
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
static void
ipcrypto_oaep_mask(const EVP_MD* hash,
Ip_u8* seed,
int seed_len,
Ip_u8* data,
int data_len)
{
unsigned count = 0;
ip_assert(EVP_MD_size(hash) <= EVP_MAX_MD_SIZE);
while (data_len > 0) {
int i, max = (data_len > EVP_MD_size(hash) ? EVP_MD_size(hash) : data_len);
EVP_MD_CTX md_ctx;
unsigned char counter[4], hash_buf[EVP_MAX_MD_SIZE];
unsigned int hash_size = sizeof(hash_buf);
IP_SET_HTONL(counter, count);
EVP_MD_CTX_init(&md_ctx);
EVP_DigestInit(&md_ctx, hash);
EVP_DigestUpdate(&md_ctx, seed, seed_len);
EVP_DigestUpdate(&md_ctx, counter, 4);
EVP_DigestFinal(&md_ctx, hash_buf, &hash_size);
count++;
for (i = 0; i < max; i++)
data[i] ^= hash_buf[i];
data += max;
data_len -= max;
}
}
/*
*===========================================================================
* ipcrypto_rsa_oaep
*===========================================================================
* Description:
+----------+---------+-------+
DB = | lHash | PS | M |
+----------+---------+-------+
|
+----------+ V
| seed |--> MGF ---> xor
+----------+ |
| |
+--+ V |
|00| xor <----- MGF <-----|
+--+ | |
| | |
V V V
+--+----------+----------------------------+
EM = |00|maskedSeed| maskedDB |
+--+----------+----------------------------+
* Parameters:
*
* Returns:
*
*/
IP_GLOBAL void
ipcrypto_rsa_oaep_encode(const EVP_MD* hash,
unsigned char *in,
int inlen,
unsigned char *out,
int outlen)
{
int k = outlen; /* length in octets of the RSA modulus */
int i;
const int hLen = EVP_MD_size(hash);
unsigned int md_size;
/* The length of the input data must be at most k - 2hLen - 2. */
ip_assert(inlen > 0 && inlen <= k - 2*hLen - 2);
/* Leading byte zero. */
out[0] = 0;
/* At position 1, the seed: hLen bytes of random data. */
for (i = 1; i < hLen+1; i+=4)
{
Ip_u32 rnd;
rnd = ipcom_random();
if ((hLen+1)-i >=4)
ipcom_memcpy(&out[i], &rnd, 4);
else
ipcom_memcpy(&out[i], &rnd, (hLen+1)-i);
}
/* The data block DB starts at position 1+hLen, consisting of: */
/* The hash of the label (only an empty label supported) */
EVP_Digest(IP_NULL, 0, &out[1+hLen], &md_size, hash, IP_NULL);
/* Zero octets padding */
ipcom_memset(out + 2*hLen + 1, 0, outlen - (2*hLen + 1));
/* A single 1 octet, thereafter the input message data. */
out[outlen - inlen - 1] = 1;
ipcom_memcpy(out + outlen - inlen, in, inlen);
/* Use the seed data to mask the block DB with the seed data */
ipcrypto_oaep_mask(hash, out+1, hLen, out+hLen+1, outlen-hLen-1);
/* Mask the masked DB with the seed. */
ipcrypto_oaep_mask(hash, out+hLen+1, outlen-hLen-1, out+1, hLen);
}
/*
*===========================================================================
* ipcrypto_rsa_oaep_decode
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ip_err
ipcrypto_rsa_oaep_decode(const EVP_MD* hash,
unsigned char *in,
int in_len,
unsigned char *out,
int* out_len)
{
const int hLen = EVP_MD_size(hash);
int pos;
/* Unmask seed */
ipcrypto_oaep_mask(hash, in+1+hLen, in_len-(1+hLen), in+1, hLen);
/* Unmask cleartext message, using seed */
ipcrypto_oaep_mask(hash, in+1, hLen, in+1+hLen, in_len-(1+hLen));
/* Proceed past section of null padding */
pos = 2*hLen+1;
while (in[pos] == 0 && pos < in_len)
pos++;
if (in[pos] != 1 || pos > in_len-1)
return IPCOM_ERR_INVALID_ARG;
pos++; /* Proceed past '1' byte */
if (*out_len < in_len-pos-1)
return IPCOM_ERR_INVALID_ARG;
*out_len = in_len-pos;
ipcom_memcpy(out, &in[pos], *out_len);
return IPCOM_SUCCESS;
}