diff -Naur ./trunk/src/tools/pkcs11-tool.c ./trunk/src/tools/pkcs11-tool.c
--- ./trunk/src/tools/pkcs11-tool.c	2008-12-03 07:52:00.000000000 +0000
+++ ./trunk/src/tools/pkcs11-tool.c	2008-12-03 09:10:14.000000000 +0000
@@ -928,10 +928,12 @@
 		CK_OBJECT_HANDLE key)
 {
 	unsigned char	buffer[512];
+	unsigned char	sig[512];
 	CK_MECHANISM	mech;
 	CK_RV		rv;
 	CK_ULONG	sig_len;
 	int		fd, r;
+	bool		single_sign = false;
 
 	if (opt_mechanism == NO_MECHANISM) {
 		opt_mechanism = find_mechanism(slot, CKF_SIGN|CKF_HW, 1);
@@ -953,16 +955,28 @@
 
 	while ((r = read(fd, buffer, sizeof(buffer))) > 0) {
 		rv = p11->C_SignUpdate(session, buffer, r);
-		if (rv != CKR_OK)
-			p11_fatal("C_SignUpdate", rv);
+		if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
+			single_sign = true;
+			break;
+		} else {
+			if (rv != CKR_OK)
+				p11_fatal("C_SignUpdate", rv);
+		}
 	}
 	if (fd != 0)
 		close(fd);
 
-	sig_len = sizeof(buffer);
-	rv = p11->C_SignFinal(session, buffer, &sig_len);
-	if (rv != CKR_OK)
-		p11_fatal("C_SignFinal", rv);
+	if (single_sign) {
+		sig_len = sizeof(sig);
+		rv = p11->C_Sign(session, buffer, r, sig, &sig_len);
+		if (rv != CKR_OK)
+			p11_fatal("C_Sign", rv);
+	} else {
+		sig_len = sizeof(buffer);
+		rv = p11->C_SignFinal(session, buffer, &sig_len);
+		if (rv != CKR_OK)
+			p11_fatal("C_SignFinal", rv);
+	}
 
 	if (opt_output == NULL)
 		fd = 1;
@@ -970,7 +984,10 @@
 		util_fatal("failed to open %s: %m", opt_output);
 	}
 
-	r = write(fd, buffer, sig_len);
+	if (single_sign)
+		r = write(fd, sig, sig_len);
+	else
+		r = write(fd, buffer, sig_len);
 	if (r < 0)
 		util_fatal("Failed to write to %s: %m", opt_output);
 	if (fd != 1)
