Fix for extended length Le in decipher
[gnupg.git] / scd / iso7816.c
index f1ee0da..e3f2c1b 100644 (file)
@@ -15,8 +15,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * $Id$
  */
 
 #include <config.h>
@@ -460,7 +458,7 @@ iso7816_get_data (int slot, int extended_mode, int tag,
    bytes. */
 gpg_error_t
 iso7816_put_data (int slot, int extended_mode, int tag,
-                  const unsigned char *data, size_t datalen)
+                  const void *data, size_t datalen)
 {
   int sw;
 
@@ -473,7 +471,7 @@ iso7816_put_data (int slot, int extended_mode, int tag,
 /* Same as iso7816_put_data but uses an odd instruction byte.  */
 gpg_error_t
 iso7816_put_data_odd (int slot, int extended_mode, int tag,
-                      const unsigned char *data, size_t datalen)
+                      const void *data, size_t datalen)
 {
   int sw;
 
@@ -545,10 +543,11 @@ iso7816_compute_ds (int slot, int extended_mode,
    indicator to be used.  It should be 0 if no padding is required, a
    value of -1 suppresses the padding byte.  On success 0 is returned
    and the plaintext is available in a newly allocated buffer stored
-   at RESULT with its length stored at RESULTLEN. */
+   at RESULT with its length stored at RESULTLEN.  For LE see
+   do_generate_keypair. */
 gpg_error_t
 iso7816_decipher (int slot, int extended_mode, 
-                  const unsigned char *data, size_t datalen,
+                  const unsigned char *data, size_t datalen, int le,
                   int padind, unsigned char **result, size_t *resultlen)
 {
   int sw;
@@ -559,6 +558,11 @@ iso7816_decipher (int slot, int extended_mode,
   *result = NULL;
   *resultlen = 0;
 
+  if (!extended_mode)
+    le = 256;  /* Ignore provided Le and use what apdu_send uses. */
+  else if (le >= 0 && le < 256)
+    le = 256;
+
   if (padind >= 0)
     {
       /* We need to prepend the padding indicator. */
@@ -568,18 +572,18 @@ iso7816_decipher (int slot, int extended_mode,
       
       *buf = padind; /* Padding indicator. */
       memcpy (buf+1, data, datalen);
-      sw = apdu_send (slot, extended_mode, 
-                      0x00, CMD_PSO, 0x80, 0x86,
-                      datalen+1, (char*)buf,
-                      result, resultlen);
+      sw = apdu_send_le (slot, extended_mode, 
+                         0x00, CMD_PSO, 0x80, 0x86,
+                         datalen+1, (char*)buf, le,
+                         result, resultlen);
       xfree (buf);
     }
   else
     {
-      sw = apdu_send (slot, extended_mode,
-                      0x00, CMD_PSO, 0x80, 0x86,
-                      datalen, (const char *)data,
-                      result, resultlen);
+      sw = apdu_send_le (slot, extended_mode,
+                         0x00, CMD_PSO, 0x80, 0x86,
+                         datalen, (const char *)data, le,
+                         result, resultlen);
     }
   if (sw != SW_SUCCESS)
     {