diff options
author | Dina K Nimeh <Dina.Nimeh@Sun.COM> | 2010-06-07 08:54:25 -0700 |
---|---|---|
committer | Dina K Nimeh <Dina.Nimeh@Sun.COM> | 2010-06-07 08:54:25 -0700 |
commit | 726fad2a65f16c200a03969c29cb5c86c2d427db (patch) | |
tree | aca280cc44a7b599ab39116a9229a98428f7c9d7 /usr/src/common/crypto/padding/pkcs7.c | |
parent | ad559bec55fd74f310399483501e1fa231f65528 (diff) | |
download | illumos-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.c | 121 |
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); +} |