Rewrite RSA_padding_add_PKCS1_type_{1,2}() with CBS/CBB.
authorjsing <jsing@openbsd.org>
Sat, 30 Mar 2024 04:34:17 +0000 (04:34 +0000)
committerjsing <jsing@openbsd.org>
Sat, 30 Mar 2024 04:34:17 +0000 (04:34 +0000)
ok tb@

lib/libcrypto/rsa/rsa_pk1.c

index 38f7c0b..8e56a8c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: rsa_pk1.c,v 1.16 2023/07/08 12:26:45 beck Exp $ */
+/* $OpenBSD: rsa_pk1.c,v 1.17 2024/03/30 04:34:17 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/err.h>
 #include <openssl/rsa.h>
 
+#include "bytestring.h"
+
 int
 RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
     const unsigned char *from, int flen)
 {
-       int j;
-       unsigned char *p;
+       CBB cbb;
+       int i;
+       int ret = 0;
+
+       /*
+        * Pad data block with PKCS1 type 1 padding - RFC 2313, section 8.1.
+        */
+
+       memset(&cbb, 0, sizeof(cbb));
 
-       if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) {
+       if (flen < 0 || tlen < 0)
+               goto err;
+
+       if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
                RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-               return 0;
+               goto err;
+       }
+
+       if (!CBB_init_fixed(&cbb, to, tlen))
+               goto err;
+
+       /*
+        * Add leading NUL, block type (0x01), padding bytes (0xff) and
+        * trailing NUL.
+        */
+       if (!CBB_add_u8(&cbb, 0))
+               goto err;
+       if (!CBB_add_u8(&cbb, 1))
+               goto err;
+       for (i = 0; i < tlen - 3 - flen; i++) {
+               if (!CBB_add_u8(&cbb, 0xff))
+                       goto err;
        }
+       if (!CBB_add_u8(&cbb, 0))
+               goto err;
+
+       /* Now add the actual data. */
+       if (!CBB_add_bytes(&cbb, from, flen))
+               goto err;
 
-       p = (unsigned char *)to;
+       if (!CBB_finish(&cbb, NULL, NULL))
+               goto err;
 
-       *(p++) = 0;
-       *(p++) = 1; /* Private Key BT (Block Type) */
+       ret = 1;
 
-       /* pad out with 0xff data */
-       j = tlen - 3 - flen;
-       memset(p, 0xff, j);
-       p += j;
-       *(p++) = '\0';
-       memcpy(p, from, flen);
+ err:
+       CBB_cleanup(&cbb);
 
-       return 1;
+       return ret;
 }
 LCRYPTO_ALIAS(RSA_padding_add_PKCS1_type_1);
 
@@ -146,33 +176,69 @@ int
 RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
     const unsigned char *from, int flen)
 {
-       int i, j;
-       unsigned char *p;
+       uint8_t padding[256];
+       uint8_t pad;
+       CBB cbb;
+       CBS cbs;
+       int i;
+       int ret = 0;
+
+       /*
+        * Pad data block with PKCS1 type 2 padding - RFC 2313, section 8.1.
+        */
 
-       if (flen > tlen - 11) {
+       memset(&cbb, 0, sizeof(cbb));
+       CBS_init(&cbs, NULL, 0);
+
+       if (flen < 0 || tlen < 0)
+               goto err;
+
+       if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
                RSAerror(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-               return 0;
+               goto err;
        }
 
-       p = (unsigned char *)to;
-
-       *(p++) = 0;
-       *(p++) = 2; /* Public Key BT (Block Type) */
+       if (!CBB_init_fixed(&cbb, to, tlen))
+               goto err;
 
-       /* pad out with non-zero random data */
-       j = tlen - 3 - flen;
+       /*
+        * Add leading NUL, block type (0x02), padding bytes (random non-zero
+        * bytes) and trailing NUL.
+        */
+       if (!CBB_add_u8(&cbb, 0))
+               goto err;
+       if (!CBB_add_u8(&cbb, 2))
+               goto err;
+       for (i = 0; i < tlen - 3 - flen; i++) {
+               do {
+                       if (CBS_len(&cbs) == 0) {
+                               arc4random_buf(padding, sizeof(padding));
+                               CBS_init(&cbs, padding, sizeof(padding));
+                       }
+                       if (!CBS_get_u8(&cbs, &pad))
+                               goto err;
+               } while (pad == 0);
 
-       arc4random_buf(p, j);
-       for (i = 0; i < j; i++) {
-               while (*p == '\0')
-                       arc4random_buf(p, 1);
-               p++;
+               if (!CBB_add_u8(&cbb, pad))
+                       goto err;
        }
+       if (!CBB_add_u8(&cbb, 0))
+               goto err;
+
+       /* Now add the actual data. */
+       if (!CBB_add_bytes(&cbb, from, flen))
+               goto err;
+
+       if (!CBB_finish(&cbb, NULL, NULL))
+               goto err;
+
+       ret = 1;
 
-       *(p++) = '\0';
+ err:
+       CBB_cleanup(&cbb);
+       explicit_bzero(padding, sizeof(padding));
 
-       memcpy(p, from, flen);
-       return 1;
+       return ret;
 }
 LCRYPTO_ALIAS(RSA_padding_add_PKCS1_type_2);