Check-in [ebeffd66b4]
Overview
Comment:Updated to support unpadding
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ebeffd66b45d8ab6a5423d0d79713db0a938beac
User & Date: rkeene on 2010-05-17 22:22:04
Other Links: manifest | tags
Context
2010-05-17
23:11
Updated debugging output check-in: 824ac1bc2e user: rkeene tags: trunk
22:22
Updated to support unpadding check-in: ebeffd66b4 user: rkeene tags: trunk
21:50
Corrected issue with sign/decrypt buffer sizes check-in: 9aa715ce7f user: rkeene tags: trunk
Changes

Modified cackey.c from [6f8796b70d] to [b1f39a9840].

  1835   1835    * RETURN VALUE
  1836   1836    *     ...
  1837   1837    *
  1838   1838    * NOTES
  1839   1839    *     ...
  1840   1840    *
  1841   1841    */
  1842         -static ssize_t cackey_signdecrypt(struct cackey_slot *slot, struct cackey_identity *identity, unsigned char *buf, size_t buflen, unsigned char *outbuf, size_t outbuflen) {
         1842  +static ssize_t cackey_signdecrypt(struct cackey_slot *slot, struct cackey_identity *identity, unsigned char *buf, size_t buflen, unsigned char *outbuf, size_t outbuflen, int padInput, int unpadOutput) {
  1843   1843   	unsigned char *tmpbuf, *tmpbuf_s;
  1844   1844   	unsigned char bytes_to_send, p1;
         1845  +	unsigned char blocktype;
  1845   1846   	cackey_ret send_ret;
  1846   1847   	uint16_t respcode;
  1847         -	ssize_t retval;
         1848  +	ssize_t retval = 0, unpadoffset;
  1848   1849   	size_t tmpbuflen, padlen, tmpoutbuflen;
  1849         -	int free_tmpbuf = 0;
         1850  +	int free_tmpbuf = 0, sepByte = -1;
  1850   1851   	int le;
  1851   1852   
  1852   1853   	CACKEY_DEBUG_PRINTF("Called.");
  1853   1854   
  1854   1855   	if (buflen > 255) {
  1855   1856   		CACKEY_DEBUG_PRINTF("Error.  buflen is greater than 255 (buflen = %lu)", (unsigned long) buflen);
  1856   1857   
................................................................................
  1889   1890   
  1890   1891   	/* Determine identity Key size */
  1891   1892   	if (identity->pcsc_identity->keysize < 0) {
  1892   1893   		identity->pcsc_identity->keysize = x509_to_keysize(identity->pcsc_identity->certificate, identity->pcsc_identity->certificate_len);
  1893   1894   	}
  1894   1895   
  1895   1896   	/* Pad message to key size */
  1896         -	if (identity->pcsc_identity->keysize > 0) {
  1897         -		if (buflen != identity->pcsc_identity->keysize) {
  1898         -			if (buflen > (identity->pcsc_identity->keysize + 3)) {
  1899         -				CACKEY_DEBUG_PRINTF("Error.  Message is too large to sign/decrypt");
  1900         -
  1901         -				return(-1);
  1902         -			}
  1903         -
  1904         -			tmpbuflen = identity->pcsc_identity->keysize;
  1905         -			tmpbuf = malloc(tmpbuflen);
  1906         -			free_tmpbuf = 1;
  1907         -
  1908         -			padlen = tmpbuflen - buflen - 3;
  1909         -
  1910         -			tmpbuf[0] = 0x00;
  1911         -			tmpbuf[1] = 0x01;
  1912         -			memset(&tmpbuf[2], 0xFF, padlen);
  1913         -			tmpbuf[padlen + 2]= 0x00;
  1914         -			memcpy(&tmpbuf[padlen + 3], buf, buflen);
  1915         -
  1916         -			CACKEY_DEBUG_PRINTBUF("Unpadded:", buf, buflen);
  1917         -			CACKEY_DEBUG_PRINTBUF("Padded:", tmpbuf, tmpbuflen);
         1897  +	if (padInput) {
         1898  +		if (identity->pcsc_identity->keysize > 0) {
         1899  +			if (buflen != identity->pcsc_identity->keysize) {
         1900  +				if (buflen > (identity->pcsc_identity->keysize + 3)) {
         1901  +					CACKEY_DEBUG_PRINTF("Error.  Message is too large to sign/decrypt");
         1902  +
         1903  +					return(-1);
         1904  +				}
         1905  +
         1906  +				tmpbuflen = identity->pcsc_identity->keysize;
         1907  +				tmpbuf = malloc(tmpbuflen);
         1908  +				free_tmpbuf = 1;
         1909  +
         1910  +				padlen = tmpbuflen - buflen - 3;
         1911  +
         1912  +				tmpbuf[0] = 0x00;
         1913  +				tmpbuf[1] = 0x01;
         1914  +				memset(&tmpbuf[2], 0xFF, padlen);
         1915  +				tmpbuf[padlen + 2]= 0x00;
         1916  +				memcpy(&tmpbuf[padlen + 3], buf, buflen);
         1917  +
         1918  +				CACKEY_DEBUG_PRINTBUF("Unpadded:", buf, buflen);
         1919  +				CACKEY_DEBUG_PRINTBUF("Padded:", tmpbuf, tmpbuflen);
         1920  +			} else {
         1921  +				tmpbuf = buf;
         1922  +				tmpbuflen = buflen;
         1923  +				free_tmpbuf = 0;
         1924  +				padlen = 0;
         1925  +			}
  1918   1926   		} else {
         1927  +			CACKEY_DEBUG_PRINTF("Unable to determine key size, hoping the message is properly padded!");
         1928  +
  1919   1929   			tmpbuf = buf;
  1920   1930   			tmpbuflen = buflen;
  1921   1931   			free_tmpbuf = 0;
  1922   1932   			padlen = 0;
  1923   1933   		}
  1924   1934   	} else {
  1925         -		CACKEY_DEBUG_PRINTF("Unable to determine key size, hoping the message is properly padded!");
  1926         -
  1927   1935   		tmpbuf = buf;
  1928   1936   		tmpbuflen = buflen;
  1929   1937   		free_tmpbuf = 0;
  1930   1938   		padlen = 0;
  1931   1939   	}
  1932   1940   
  1933   1941   	/* Begin transaction */
................................................................................
  1997   2005   		CACKEY_DEBUG_PRINTF("Outbuflen exceeds maximum value, returning in failure. (max = %li, outbuflen = %lu)", (long) _POSIX_SSIZE_MAX, (unsigned long) outbuflen);
  1998   2006   
  1999   2007   		return(-1);
  2000   2008   	}
  2001   2009   #  endif
  2002   2010   #endif
  2003   2011   
  2004         -	CACKEY_DEBUG_PRINTF("Returning in success.");
         2012  +	/* Unpad reply */
         2013  +	if (unpadOutput) {
         2014  +		if (retval < 2) {
         2015  +			CACKEY_DEBUG_PRINTF("Reply is too small, we are not able to unpad -- passing back and hoping for the best!");
         2016  +
         2017  +			return(retval);
         2018  +		}
         2019  +
         2020  +		blocktype = outbuf[0];
         2021  +		unpadoffset = 0;
         2022  +
         2023  +		switch (blocktype) {
         2024  +			case 0x00:
         2025  +				/* Padding Scheme 1, the first non-zero byte is the start of data */
         2026  +				for (unpadoffset = 1; unpadoffset < retval; unpadoffset++) {
         2027  +					if (outbuf[unpadoffset] != 0x00) {
         2028  +						break;
         2029  +					}
         2030  +				}
         2031  +				break;
         2032  +			case 0x01:
         2033  +				/* Padding Scheme 2, pad bytes are 0xFF followed by 0x00 */
         2034  +				for (unpadoffset = 1; unpadoffset < retval; unpadoffset++) {
         2035  +					if (outbuf[unpadoffset] != 0xFF) {
         2036  +						if (outbuf[unpadoffset] == 0x00) {
         2037  +							unpadoffset++;
         2038  +
         2039  +							break;
         2040  +						} else {
         2041  +							CACKEY_DEBUG_PRINTF("Invalid padding data found, returning in failure, should have been 0x00 found 0x%02x", (unsigned int) outbuf[unpadoffset]);
         2042  +
         2043  +							return(-1);
         2044  +						}
         2045  +					} else {
         2046  +						CACKEY_DEBUG_PRINTF("Invalid padding data found, returning in failure, should have been 0xFF found 0x%02x", (unsigned int) outbuf[unpadoffset]);
         2047  +
         2048  +						return(-1);
         2049  +					}
         2050  +				}
         2051  +				break;
         2052  +			case 0x02:
         2053  +				/* Padding Scheme 3, pad bytes are non-zero first non-zero byte found is the pad byte */
         2054  +				for (unpadoffset = 1; unpadoffset < retval; unpadoffset++) {
         2055  +					if (outbuf[unpadoffset] == 0x00) {
         2056  +						continue;
         2057  +					}
         2058  +
         2059  +					if (sepByte == -1) {
         2060  +						sepByte = outbuf[unpadoffset];
         2061  +
         2062  +						continue;
         2063  +					}
         2064  +
         2065  +					if (outbuf[unpadoffset] == sepByte) {
         2066  +						unpadoffset++;
         2067  +
         2068  +						break;
         2069  +					}
         2070  +				}
         2071  +				break;
         2072  +		}
         2073  +
         2074  +		if (unpadoffset > retval) {
         2075  +			CACKEY_DEBUG_PRINTF("Offset greater than reply size, aborting.  (unpadoffset = %lu, retval = %lu)", (unsigned long) unpadoffset, (unsigned long) retval);
         2076  +
         2077  +			return(-1);
         2078  +		}
         2079  +
         2080  +		CACKEY_DEBUG_PRINTBUF("Padded:", outbuf, retval);
         2081  +
         2082  +		retval -= unpadoffset;
         2083  +		memmove(outbuf + unpadoffset, outbuf, retval);
         2084  +
         2085  +		CACKEY_DEBUG_PRINTBUF("Unpadded:", outbuf, retval);
         2086  +	}
         2087  +
         2088  +
         2089  +	CACKEY_DEBUG_PRINTF("Returning in success, signed %li bytes", (long) retval);
  2005   2090   
  2006   2091   	return(retval);
  2007   2092   }
  2008   2093   
  2009   2094   /*
  2010   2095    * SYNPOSIS
  2011   2096    *     ...
................................................................................
  4470   4555   		
  4471   4556   		return(CKR_OPERATION_NOT_INITIALIZED);
  4472   4557   	}
  4473   4558   
  4474   4559   	switch (cackey_sessions[hSession].decrypt_mechanism) {
  4475   4560   		case CKM_RSA_PKCS:
  4476   4561   			/* Ask card to decrypt */
  4477         -			buflen = cackey_signdecrypt(&cackey_slots[cackey_sessions[hSession].slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf));
         4562  +			buflen = cackey_signdecrypt(&cackey_slots[cackey_sessions[hSession].slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1);
  4478   4563   
  4479   4564   			if (buflen < 0) {
  4480   4565   				/* Decryption failed. */
  4481   4566   				retval = CKR_GENERAL_ERROR;
  4482   4567   			} else if (((unsigned long) buflen) > *pulPartLen && pPart) {
  4483   4568   				/* Decrypted data too large */
  4484   4569   				retval = CKR_BUFFER_TOO_SMALL;
................................................................................
  4906   4991   		return(CKR_OPERATION_NOT_INITIALIZED);
  4907   4992   	}
  4908   4993   
  4909   4994   	switch (cackey_sessions[hSession].sign_mechanism) {
  4910   4995   		case CKM_RSA_PKCS:
  4911   4996   			/* Ask card to sign */
  4912   4997   			CACKEY_DEBUG_PRINTF("Asking to decrypt from identity %p in session %lu", cackey_sessions[hSession].sign_identity, (unsigned long) hSession);
  4913         -			sigbuflen = cackey_signdecrypt(&cackey_slots[cackey_sessions[hSession].slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_buflen, sigbuf, sizeof(sigbuf));
         4998  +			sigbuflen = cackey_signdecrypt(&cackey_slots[cackey_sessions[hSession].slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_buflen, sigbuf, sizeof(sigbuf), 1, 0);
  4914   4999   
  4915   5000   			if (sigbuflen < 0) {
  4916   5001   				/* Signing failed. */
  4917   5002   				retval = CKR_GENERAL_ERROR;
  4918   5003   			} else if (((unsigned long) sigbuflen) > *pulSignatureLen && pSignature) {
  4919   5004   				/* Signed data too large */
  4920   5005   				retval = CKR_BUFFER_TOO_SMALL;