726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh/*
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * CDDL HEADER START
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * The contents of this file are subject to the terms of the
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * Common Development and Distribution License (the "License").
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * You may not use this file except in compliance with the License.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * or http://www.opensolaris.org/os/licensing.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * See the License for the specific language governing permissions
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * and limitations under the License.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * When distributing Covered Code, include this CDDL HEADER in each
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * If applicable, add the following below this CDDL HEADER, with the
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * fields enclosed by brackets "[]" replaced with your own identifying
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * information: Portions Copyright [yyyy] [name of copyright owner]
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * CDDL HEADER END
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh/*
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh/*
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * This file contains padding helper routines common to
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * the PKCS11 soft token code and the kernel crypto code.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#include <sys/types.h>
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#include "padding.h"
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#ifdef _KERNEL
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#include <sys/param.h>
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#else
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#include <strings.h>
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#include <cryptoutil.h>
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#endif
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh/*
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * To create a block type "02" encryption block for RSA PKCS encryption
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * process.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * This is EME-PKCS1-v1_5 encoding as described in RSA PKCS#1.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * The RSA PKCS Padding before encryption is in the following format:
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * +----+----+--------------------+----+-----------------------------+
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * |0x00|0x02| 8 bytes or more RN |0x00| DATA |
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * +----+----+--------------------+----+-----------------------------+
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * To create a block type "01" block for RSA PKCS signature process.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * This EMSA-PKCS1-1_5 encoding as decribed in RSA PKCS#1.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * The RSA PKCS Padding before Signing is in the following format:
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * +----+----+----------------------+----+-----------------------------+
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * |0x00|0x01| 8 bytes of more 0xFF |0x00| DATA |
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * +----+----+----------------------+----+-----------------------------+
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimehint
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimehpkcs1_encode(int method, uint8_t *databuf, size_t datalen, uint8_t *padbuf,
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh size_t padbuflen)
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh{
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh size_t padlen;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh int rv;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh padlen = padbuflen - datalen;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh if (padlen < MIN_PKCS1_PADLEN) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (CKR_DATA_LEN_RANGE);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh }
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh rv = 0;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh padbuf[0] = 0x00;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh padbuf[1] = (method == PKCS1_ENCRYPT) ? 0x02 : 0x01;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh if (method == PKCS1_ENCRYPT) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#ifdef _KERNEL
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh rv = knzero_random_generator(padbuf + 2, padlen - 3);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#else
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh rv = (pkcs11_get_nzero_urandom(padbuf + 2, padlen - 3) < 0) ?
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh CKR_DEVICE_ERROR : 0;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#endif
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh } else if (method == PKCS1_SIGN) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#ifdef _KERNEL
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh kmemset(padbuf + 2, 0xFF, padlen - 3);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#else
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh (void) memset(padbuf + 2, 0xFF, padlen - 3);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh#endif
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh }
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh if (rv != 0) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (rv);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh }
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh padbuf[padlen - 1] = 0x00;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh bcopy(databuf, padbuf + padlen, datalen);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (0);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh}
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh/*
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * The RSA PKCS Padding in the following format:
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * +----+----+-------------------------+----+------------------------+
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * |0x00| BT | 8 bytes or more padding |0x00| DATA |
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * +----+----+-+++++-------------------+----+------------------------+
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * where BT is block type: 0x02 for encrypt/decrypt, 0x01 for sign/verify
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * 'padbuf' points to the recovered message. Strip off the padding and
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * validate it as much as possible. 'plen' is changed to hold the actual
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh * data length.
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimehint
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimehpkcs1_decode(int method, uint8_t *padbuf, size_t *plen)
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh{
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh int rv = ((method == PKCS1_DECRYPT) ? CKR_ENCRYPTED_DATA_INVALID :
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh CKR_SIGNATURE_INVALID);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh int i;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh /* Check to see if the recovered data is padded is 0x0002 or 0x0001. */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh if (padbuf[0] != 0x00 || padbuf[1] != (method == PKCS1_DECRYPT ?
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh 0x02 : 0x01)) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (rv);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh }
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh /* Remove all the random bits up to 0x00 (= NULL char) */
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh for (i = 2; (*plen - i) > 0; i++) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh if (padbuf[i] == 0x00) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh i++;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh if (i < MIN_PKCS1_PADLEN) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (rv);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh }
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh *plen -= i;
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (0);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh } else if (method == PKCS1_VERIFY && padbuf[i] != 0xFF) {
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (rv);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh }
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh }
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh return (rv);
726fad2a65f16c200a03969c29cb5c86c2d427dbDina K Nimeh}