4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
27 * This file contains padding helper routines common to
28 * the PKCS11 soft token code and the kernel crypto code.
31 #include <sys/types.h>
35 #include <sys/param.h>
38 #include <cryptoutil.h>
42 * This is padding as decribed in Section 10.3 of RSA PKCS#7.
44 * The RSA PKCS Padding is in the following format:
45 * +-----------------------------+----+-------------+
46 * | DATA |0x0k|0x0k|...|0x0k|
47 * +-----------------------------+----+----+---+----+
48 * where 0x0k is if data_len mod multiple = multiple - k
49 * and multiple < 256 and 1 <= k <= multiple
51 * If databuf is non NULL, padbuf must be large enough
52 * to contain both databuf and the padding. databuf and
53 * padbuf may be the same buffer.
55 * +-----------------------------+
57 * +-----------------------------+
60 * +-----------------------------+----+-------------+
61 * | DATA |0x0k|0x0k|...|0x0k|
62 * +-----------------------------+----+----+---+----+
65 * If databuf is NULL, padbuf only needs to be large
66 * enough for the padding, and datalen must still be
67 * provided to compute the padding value:
69 * +----+-------------+
70 * |0x0k|0x0k|...|0x0k|
71 * +----+----+---+----+
75 pkcs7_encode(uint8_t *databuf
, size_t datalen
, uint8_t *padbuf
,
76 size_t padbuflen
, uint8_t multiple
)
80 padlen
= multiple
- (datalen
% multiple
);
84 if (padlen
> padbuflen
- datalen
) {
85 return (CKR_DATA_LEN_RANGE
);
88 bcopy(databuf
, padbuf
, datalen
);
89 (void) memset(padbuf
+ datalen
, padlen
& 0xff, padlen
);
95 * 'padbuf' points to the recovered message. Strip off the padding and
96 * validate it as much as possible. 'plen' is changed to hold the actual
97 * data length. 'padbuf' is unchanged.
100 pkcs7_decode(uint8_t *padbuf
, size_t *plen
)
105 /* Recover the padding value, even if padbuf has trailing nulls */
106 while (*plen
> 0 && (padlen
= padbuf
[*plen
- 1]) == 0)
109 /* Must have non-zero padding */
111 return (CKR_ENCRYPTED_DATA_INVALID
);
113 /* Count back from all padding bytes; lint tag is for *plen-1-i >= 0 */
114 /* LINTED E_SUSPICIOUS_COMPARISON */
115 for (i
= 0; i
< padlen
&& (*plen
- 1 - i
) >= 0; i
++) {
116 if (padbuf
[*plen
- 1 - i
] != (padlen
& 0xff))
117 return (CKR_ENCRYPTED_DATA_INVALID
);