summaryrefslogtreecommitdiff
path: root/usr/src/common/crypto/padding/pkcs7.c
diff options
context:
space:
mode:
authorDina K Nimeh <Dina.Nimeh@Sun.COM>2010-06-07 08:54:25 -0700
committerDina K Nimeh <Dina.Nimeh@Sun.COM>2010-06-07 08:54:25 -0700
commit726fad2a65f16c200a03969c29cb5c86c2d427db (patch)
treeaca280cc44a7b599ab39116a9229a98428f7c9d7 /usr/src/common/crypto/padding/pkcs7.c
parentad559bec55fd74f310399483501e1fa231f65528 (diff)
downloadillumos-joyent-726fad2a65f16c200a03969c29cb5c86c2d427db.tar.gz
6875651 move asymmetric crypto to libsoftcrypto
6816864 collect together padding methods used by PKCS#11 6917508 bignum library needs big random number function 6249983 softtoken based RSA/DSA slow on Niagara 6917506 arcfour lint check missing from usr/src/uts/sun4v/Makefile 6917513 move softFipsDSAUtil.c to common/crypto/fips/fips_dsa_util.c 6834849 dsa_sign() produces invalid signature when pkcs11 engine is used via openssl(1) for certain keys
Diffstat (limited to 'usr/src/common/crypto/padding/pkcs7.c')
-rw-r--r--usr/src/common/crypto/padding/pkcs7.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/usr/src/common/crypto/padding/pkcs7.c b/usr/src/common/crypto/padding/pkcs7.c
new file mode 100644
index 0000000000..e1277c7bf8
--- /dev/null
+++ b/usr/src/common/crypto/padding/pkcs7.c
@@ -0,0 +1,121 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This file contains padding helper routines common to
+ * the PKCS11 soft token code and the kernel crypto code.
+ */
+
+#include <sys/types.h>
+#include "padding.h"
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#else
+#include <strings.h>
+#include <cryptoutil.h>
+#endif
+
+/*
+ * This is padding as decribed in Section 10.3 of RSA PKCS#7.
+ *
+ * The RSA PKCS Padding is in the following format:
+ * +-----------------------------+----+-------------+
+ * | DATA |0x0k|0x0k|...|0x0k|
+ * +-----------------------------+----+----+---+----+
+ * where 0x0k is if data_len mod multiple = multiple - k
+ * and multiple < 256 and 1 <= k <= multiple
+ *
+ * If databuf is non NULL, padbuf must be large enough
+ * to contain both databuf and the padding. databuf and
+ * padbuf may be the same buffer.
+ * databuf:
+ * +-----------------------------+
+ * | DATA |
+ * +-----------------------------+
+ * datalen
+ * padbuf:
+ * +-----------------------------+----+-------------+
+ * | DATA |0x0k|0x0k|...|0x0k|
+ * +-----------------------------+----+----+---+----+
+ * datalen padbuflen
+ *
+ * If databuf is NULL, padbuf only needs to be large
+ * enough for the padding, and datalen must still be
+ * provided to compute the padding value:
+ * padbuf:
+ * +----+-------------+
+ * |0x0k|0x0k|...|0x0k|
+ * +----+----+---+----+
+ * datalen padbuflen
+ */
+int
+pkcs7_encode(uint8_t *databuf, size_t datalen, uint8_t *padbuf,
+ size_t padbuflen, uint8_t multiple)
+{
+ size_t padlen;
+
+ padlen = multiple - (datalen % multiple);
+ if (databuf == NULL)
+ datalen = 0;
+
+ if (padlen > padbuflen - datalen) {
+ return (CKR_DATA_LEN_RANGE);
+ }
+
+ bcopy(databuf, padbuf, datalen);
+ (void) memset(padbuf + datalen, padlen & 0xff, padlen);
+
+ return (0);
+}
+
+/*
+ * 'padbuf' points to the recovered message. Strip off the padding and
+ * validate it as much as possible. 'plen' is changed to hold the actual
+ * data length. 'padbuf' is unchanged.
+ */
+int
+pkcs7_decode(uint8_t *padbuf, size_t *plen)
+{
+ int i;
+ size_t padlen;
+
+ /* Recover the padding value, even if padbuf has trailing nulls */
+ while (*plen > 0 && (padlen = padbuf[*plen - 1]) == 0)
+ (*plen)--;
+
+ /* Must have non-zero padding */
+ if (padlen == 0)
+ return (CKR_ENCRYPTED_DATA_INVALID);
+
+ /* Count back from all padding bytes; lint tag is for *plen-1-i >= 0 */
+ /* LINTED E_SUSPICIOUS_COMPARISON */
+ for (i = 0; i < padlen && (*plen - 1 - i) >= 0; i++) {
+ if (padbuf[*plen - 1 - i] != (padlen & 0xff))
+ return (CKR_ENCRYPTED_DATA_INVALID);
+ }
+ *plen -= i;
+ return (0);
+}