1 /* crypto/rsa/rsa_oaep.c */
2 /* Written by Ulf Moeller. This software is distributed on an "AS IS"
3 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
5 /* EME_OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
7 #if !defined(NO_SHA) && !defined(NO_SHA1)
10 #include <openssl/bn.h>
11 #include <openssl/rsa.h>
12 #include <openssl/sha.h>
13 #include <openssl/rand.h>
15 int MGF1(unsigned char *mask
, long len
, unsigned char *seed
, long seedlen
);
17 int RSA_padding_add_PKCS1_OAEP(unsigned char *to
, int tlen
,
18 unsigned char *from
, int flen
, unsigned char *param
, int plen
)
20 int i
, emlen
= tlen
- 1;
21 unsigned char *db
, *seed
;
22 unsigned char *dbmask
, seedmask
[SHA_DIGEST_LENGTH
];
24 if (flen
> emlen
- 2 * SHA_DIGEST_LENGTH
- 1)
26 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP
,
27 RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE
);
31 if (emlen
< 2 * SHA_DIGEST_LENGTH
+ 1)
33 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP
, RSA_R_KEY_SIZE_TOO_SMALL
);
37 dbmask
= OPENSSL_malloc(emlen
- SHA_DIGEST_LENGTH
);
40 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP
, ERR_R_MALLOC_FAILURE
);
46 db
= to
+ SHA_DIGEST_LENGTH
+ 1;
48 SHA1(param
, plen
, db
);
49 memset(db
+ SHA_DIGEST_LENGTH
, 0,
50 emlen
- flen
- 2 * SHA_DIGEST_LENGTH
- 1);
51 db
[emlen
- flen
- SHA_DIGEST_LENGTH
- 1] = 0x01;
52 memcpy(db
+ emlen
- flen
- SHA_DIGEST_LENGTH
, from
, (unsigned int) flen
);
53 if (RAND_bytes(seed
, SHA_DIGEST_LENGTH
) <= 0)
57 "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
61 MGF1(dbmask
, emlen
- SHA_DIGEST_LENGTH
, seed
, SHA_DIGEST_LENGTH
);
62 for (i
= 0; i
< emlen
- SHA_DIGEST_LENGTH
; i
++)
65 MGF1(seedmask
, SHA_DIGEST_LENGTH
, db
, emlen
- SHA_DIGEST_LENGTH
);
66 for (i
= 0; i
< SHA_DIGEST_LENGTH
; i
++)
67 seed
[i
] ^= seedmask
[i
];
73 int RSA_padding_check_PKCS1_OAEP(unsigned char *to
, int tlen
,
74 unsigned char *from
, int flen
, int num
, unsigned char *param
,
77 int i
, dblen
, mlen
= -1;
78 unsigned char *maskeddb
;
80 unsigned char *db
, seed
[SHA_DIGEST_LENGTH
], phash
[SHA_DIGEST_LENGTH
];
82 if (--num
< 2 * SHA_DIGEST_LENGTH
+ 1)
84 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP
, RSA_R_OAEP_DECODING_ERROR
);
88 dblen
= num
- SHA_DIGEST_LENGTH
;
89 db
= OPENSSL_malloc(dblen
);
92 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP
, ERR_R_MALLOC_FAILURE
);
97 maskeddb
= from
- lzero
+ SHA_DIGEST_LENGTH
;
99 MGF1(seed
, SHA_DIGEST_LENGTH
, maskeddb
, dblen
);
100 for (i
= lzero
; i
< SHA_DIGEST_LENGTH
; i
++)
101 seed
[i
] ^= from
[i
- lzero
];
103 MGF1(db
, dblen
, seed
, SHA_DIGEST_LENGTH
);
104 for (i
= 0; i
< dblen
; i
++)
105 db
[i
] ^= maskeddb
[i
];
107 SHA1(param
, plen
, phash
);
109 if (memcmp(db
, phash
, SHA_DIGEST_LENGTH
) != 0)
110 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP
, RSA_R_OAEP_DECODING_ERROR
);
113 for (i
= SHA_DIGEST_LENGTH
; i
< dblen
; i
++)
116 if (db
[i
] != 0x01 || i
++ >= dblen
)
117 RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP
,
118 RSA_R_OAEP_DECODING_ERROR
);
124 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP
, RSA_R_DATA_TOO_LARGE
);
128 memcpy(to
, db
+ i
, mlen
);
135 int MGF1(unsigned char *mask
, long len
, unsigned char *seed
, long seedlen
)
138 unsigned char cnt
[4];
140 unsigned char md
[SHA_DIGEST_LENGTH
];
142 for (i
= 0; outlen
< len
; i
++)
144 cnt
[0] = (i
>> 24) & 255, cnt
[1] = (i
>> 16) & 255,
145 cnt
[2] = (i
>> 8) & 255, cnt
[3] = i
& 255;
147 SHA1_Update(&c
, seed
, seedlen
);
148 SHA1_Update(&c
, cnt
, 4);
149 if (outlen
+ SHA_DIGEST_LENGTH
<= len
)
151 SHA1_Final(mask
+ outlen
, &c
);
152 outlen
+= SHA_DIGEST_LENGTH
;
157 memcpy(mask
+ outlen
, md
, len
- outlen
);