1*726fad2aSDina K Nimeh /* 2*726fad2aSDina K Nimeh * CDDL HEADER START 3*726fad2aSDina K Nimeh * 4*726fad2aSDina K Nimeh * The contents of this file are subject to the terms of the 5*726fad2aSDina K Nimeh * Common Development and Distribution License (the "License"). 6*726fad2aSDina K Nimeh * You may not use this file except in compliance with the License. 7*726fad2aSDina K Nimeh * 8*726fad2aSDina K Nimeh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*726fad2aSDina K Nimeh * or http://www.opensolaris.org/os/licensing. 10*726fad2aSDina K Nimeh * See the License for the specific language governing permissions 11*726fad2aSDina K Nimeh * and limitations under the License. 12*726fad2aSDina K Nimeh * 13*726fad2aSDina K Nimeh * When distributing Covered Code, include this CDDL HEADER in each 14*726fad2aSDina K Nimeh * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*726fad2aSDina K Nimeh * If applicable, add the following below this CDDL HEADER, with the 16*726fad2aSDina K Nimeh * fields enclosed by brackets "[]" replaced with your own identifying 17*726fad2aSDina K Nimeh * information: Portions Copyright [yyyy] [name of copyright owner] 18*726fad2aSDina K Nimeh * 19*726fad2aSDina K Nimeh * CDDL HEADER END 20*726fad2aSDina K Nimeh */ 21*726fad2aSDina K Nimeh 22*726fad2aSDina K Nimeh /* 23*726fad2aSDina K Nimeh * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 24*726fad2aSDina K Nimeh */ 25*726fad2aSDina K Nimeh 26*726fad2aSDina K Nimeh /* 27*726fad2aSDina K Nimeh * This file contains padding helper routines common to 28*726fad2aSDina K Nimeh * the PKCS11 soft token code and the kernel crypto code. 29*726fad2aSDina K Nimeh */ 30*726fad2aSDina K Nimeh 31*726fad2aSDina K Nimeh #include <sys/types.h> 32*726fad2aSDina K Nimeh #include "padding.h" 33*726fad2aSDina K Nimeh 34*726fad2aSDina K Nimeh #ifdef _KERNEL 35*726fad2aSDina K Nimeh #include <sys/param.h> 36*726fad2aSDina K Nimeh #else 37*726fad2aSDina K Nimeh #include <strings.h> 38*726fad2aSDina K Nimeh #include <cryptoutil.h> 39*726fad2aSDina K Nimeh #endif 40*726fad2aSDina K Nimeh 41*726fad2aSDina K Nimeh /* 42*726fad2aSDina K Nimeh * This is padding as decribed in Section 10.3 of RSA PKCS#7. 43*726fad2aSDina K Nimeh * 44*726fad2aSDina K Nimeh * The RSA PKCS Padding is in the following format: 45*726fad2aSDina K Nimeh * +-----------------------------+----+-------------+ 46*726fad2aSDina K Nimeh * | DATA |0x0k|0x0k|...|0x0k| 47*726fad2aSDina K Nimeh * +-----------------------------+----+----+---+----+ 48*726fad2aSDina K Nimeh * where 0x0k is if data_len mod multiple = multiple - k 49*726fad2aSDina K Nimeh * and multiple < 256 and 1 <= k <= multiple 50*726fad2aSDina K Nimeh * 51*726fad2aSDina K Nimeh * If databuf is non NULL, padbuf must be large enough 52*726fad2aSDina K Nimeh * to contain both databuf and the padding. databuf and 53*726fad2aSDina K Nimeh * padbuf may be the same buffer. 54*726fad2aSDina K Nimeh * databuf: 55*726fad2aSDina K Nimeh * +-----------------------------+ 56*726fad2aSDina K Nimeh * | DATA | 57*726fad2aSDina K Nimeh * +-----------------------------+ 58*726fad2aSDina K Nimeh * datalen 59*726fad2aSDina K Nimeh * padbuf: 60*726fad2aSDina K Nimeh * +-----------------------------+----+-------------+ 61*726fad2aSDina K Nimeh * | DATA |0x0k|0x0k|...|0x0k| 62*726fad2aSDina K Nimeh * +-----------------------------+----+----+---+----+ 63*726fad2aSDina K Nimeh * datalen padbuflen 64*726fad2aSDina K Nimeh * 65*726fad2aSDina K Nimeh * If databuf is NULL, padbuf only needs to be large 66*726fad2aSDina K Nimeh * enough for the padding, and datalen must still be 67*726fad2aSDina K Nimeh * provided to compute the padding value: 68*726fad2aSDina K Nimeh * padbuf: 69*726fad2aSDina K Nimeh * +----+-------------+ 70*726fad2aSDina K Nimeh * |0x0k|0x0k|...|0x0k| 71*726fad2aSDina K Nimeh * +----+----+---+----+ 72*726fad2aSDina K Nimeh * datalen padbuflen 73*726fad2aSDina K Nimeh */ 74*726fad2aSDina K Nimeh int 75*726fad2aSDina K Nimeh pkcs7_encode(uint8_t *databuf, size_t datalen, uint8_t *padbuf, 76*726fad2aSDina K Nimeh size_t padbuflen, uint8_t multiple) 77*726fad2aSDina K Nimeh { 78*726fad2aSDina K Nimeh size_t padlen; 79*726fad2aSDina K Nimeh 80*726fad2aSDina K Nimeh padlen = multiple - (datalen % multiple); 81*726fad2aSDina K Nimeh if (databuf == NULL) 82*726fad2aSDina K Nimeh datalen = 0; 83*726fad2aSDina K Nimeh 84*726fad2aSDina K Nimeh if (padlen > padbuflen - datalen) { 85*726fad2aSDina K Nimeh return (CKR_DATA_LEN_RANGE); 86*726fad2aSDina K Nimeh } 87*726fad2aSDina K Nimeh 88*726fad2aSDina K Nimeh bcopy(databuf, padbuf, datalen); 89*726fad2aSDina K Nimeh (void) memset(padbuf + datalen, padlen & 0xff, padlen); 90*726fad2aSDina K Nimeh 91*726fad2aSDina K Nimeh return (0); 92*726fad2aSDina K Nimeh } 93*726fad2aSDina K Nimeh 94*726fad2aSDina K Nimeh /* 95*726fad2aSDina K Nimeh * 'padbuf' points to the recovered message. Strip off the padding and 96*726fad2aSDina K Nimeh * validate it as much as possible. 'plen' is changed to hold the actual 97*726fad2aSDina K Nimeh * data length. 'padbuf' is unchanged. 98*726fad2aSDina K Nimeh */ 99*726fad2aSDina K Nimeh int 100*726fad2aSDina K Nimeh pkcs7_decode(uint8_t *padbuf, size_t *plen) 101*726fad2aSDina K Nimeh { 102*726fad2aSDina K Nimeh int i; 103*726fad2aSDina K Nimeh size_t padlen; 104*726fad2aSDina K Nimeh 105*726fad2aSDina K Nimeh /* Recover the padding value, even if padbuf has trailing nulls */ 106*726fad2aSDina K Nimeh while (*plen > 0 && (padlen = padbuf[*plen - 1]) == 0) 107*726fad2aSDina K Nimeh (*plen)--; 108*726fad2aSDina K Nimeh 109*726fad2aSDina K Nimeh /* Must have non-zero padding */ 110*726fad2aSDina K Nimeh if (padlen == 0) 111*726fad2aSDina K Nimeh return (CKR_ENCRYPTED_DATA_INVALID); 112*726fad2aSDina K Nimeh 113*726fad2aSDina K Nimeh /* Count back from all padding bytes; lint tag is for *plen-1-i >= 0 */ 114*726fad2aSDina K Nimeh /* LINTED E_SUSPICIOUS_COMPARISON */ 115*726fad2aSDina K Nimeh for (i = 0; i < padlen && (*plen - 1 - i) >= 0; i++) { 116*726fad2aSDina K Nimeh if (padbuf[*plen - 1 - i] != (padlen & 0xff)) 117*726fad2aSDina K Nimeh return (CKR_ENCRYPTED_DATA_INVALID); 118*726fad2aSDina K Nimeh } 119*726fad2aSDina K Nimeh *plen -= i; 120*726fad2aSDina K Nimeh return (0); 121*726fad2aSDina K Nimeh } 122