]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
Applied bit packing to BLISS public key
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 27 Nov 2014 10:55:54 +0000 (11:55 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 29 Nov 2014 13:51:18 +0000 (14:51 +0100)
src/libstrongswan/plugins/bliss/bliss_param_set.c
src/libstrongswan/plugins/bliss/bliss_param_set.h
src/libstrongswan/plugins/bliss/bliss_private_key.c
src/libstrongswan/plugins/bliss/bliss_public_key.c
src/libstrongswan/plugins/bliss/bliss_public_key.h

index 2fde6690a1aec151a53e433ac634b78ca7752caa..90a5bcc80adb8ea651b3186422e758cdbc77a2c9 100644 (file)
@@ -123,6 +123,7 @@ static bliss_param_set_t bliss_param_sets[] = {
                .oid = OID_BLISS_I,
                .strength = 128,
                .q = 12289,
+               .q_bits = 14,
                .q2_inv = 6145,
                .n = 512,
                .n_bits = 9,
@@ -150,6 +151,7 @@ static bliss_param_set_t bliss_param_sets[] = {
                .oid = OID_BLISS_III,
                .strength = 160,
                .q = 12289,
+               .q_bits = 14,
                .q2_inv = 6145,
                .n = 512,
                .n_bits = 9,
@@ -177,6 +179,7 @@ static bliss_param_set_t bliss_param_sets[] = {
                .oid = OID_BLISS_IV,
                .strength = 192,
                .q = 12289,
+               .q_bits = 14,
                .q2_inv = 6145,
                .n = 512,
                .n_bits = 9,
index 305d3a121f1f1fab87f8a0206c0a1737825ce768..168b6f3ddf577c0cc9556bd38247ca5b75659444 100644 (file)
@@ -65,6 +65,11 @@ struct bliss_param_set_t {
         */
        uint16_t q;
 
+       /**
+        * Number of bits in q
+        */
+       uint16_t q_bits;
+
        /**
         * Inverse of (q + 2) mod 2q
         */
index 4872ed4ff7475add242fc52de875139baff0eb1e..8391a503efc0a23e1f9af6c24782d68e1b21413f 100644 (file)
@@ -430,7 +430,7 @@ METHOD(private_key_t, get_public_key, public_key_t*,
        public_key_t *public;
        chunk_t pubkey;
 
-       pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set->n);
+       pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
        public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS,
                                                                BUILD_BLOB_ASN1_DER, pubkey, BUILD_END);
        free(pubkey.ptr);
@@ -450,7 +450,7 @@ METHOD(private_key_t, get_encoding, bool,
                        chunk_t s1_chunk, s2_chunk, pubkey;
                        bool success = TRUE;
 
-                       pubkey = bliss_public_key_encode(this->A, this->set->n);
+                       pubkey = bliss_public_key_encode(this->A, this->set);
 
                        /* Build private key as two polynomials with 8 bit coefficients */
                        s1_chunk = chunk_create(this->s1, this->set->n);
@@ -458,7 +458,7 @@ METHOD(private_key_t, get_encoding, bool,
 
                        *encoding = asn1_wrap(ASN1_SEQUENCE, "mmss",
                                                        asn1_build_known_oid(this->set->oid),
-                                                       pubkey,
+                                                       asn1_bitstring("m", pubkey),
                                                        asn1_simple_object(ASN1_OCTET_STRING, s1_chunk),
                                                        asn1_simple_object(ASN1_OCTET_STRING, s2_chunk)
                                                );
@@ -488,7 +488,7 @@ METHOD(private_key_t, get_fingerprint, bool,
                return TRUE;
        }
        success = bliss_public_key_fingerprint(this->set->oid, this->A,
-                                                                                  this->set->n, type, fp);
+                                                                                  this->set, type, fp);
        lib->encoding->cache(lib->encoding, type, this, *fp);
 
        return success;
@@ -950,7 +950,7 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
 static const asn1Object_t privkeyObjects[] = {
        { 0, "BLISSPrivateKey",         ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
        { 1,   "keyType",                       ASN1_OID,          ASN1_BODY }, /*  1 */
-       { 1,   "public",                        ASN1_OCTET_STRING, ASN1_BODY }, /*  2 */
+       { 1,   "public",                        ASN1_BIT_STRING,   ASN1_BODY }, /*  2 */
        { 1,   "secret1",                       ASN1_OCTET_STRING, ASN1_BODY }, /*  3 */
        { 1,   "secret2",                       ASN1_OCTET_STRING, ASN1_BODY }, /*  4 */
        { 0, "exit",                            ASN1_EOC,          ASN1_EXIT }
@@ -1012,11 +1012,10 @@ bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
                                }
                                break;
                        case PRIV_KEY_PUBLIC:
-                               if (object.len != 2*this->set->n)
+                               if (!bliss_public_key_from_asn1(object, this->set, &this->A))
                                {
                                        goto end;
                                }
-                               this->A = bliss_public_key_from_asn1(object, this->set->n);
                                break;
                        case PRIV_KEY_SECRET1:
                                if (object.len != this->set->n)
index 2d9ca853d2dd3ad394cba82aba8b70af83cb71bc..f1ea6854709c4e1388fcef00b1153c1d25e48c4a 100644 (file)
@@ -14,8 +14,8 @@
  */
 
 #include "bliss_public_key.h"
-#include "bliss_param_set.h"
 #include "bliss_signature.h"
+#include "bliss_bitpacker.h"
 #include "bliss_fft.h"
 #include "bliss_utils.h"
 
@@ -220,7 +220,7 @@ METHOD(public_key_t, get_encoding, bool,
 {
        bool success = TRUE;
 
-       *encoding = bliss_public_key_info_encode(this->set->oid, this->A, this->set->n);
+       *encoding = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
 
        if (type != PUBKEY_SPKI_ASN1_DER)
        {
@@ -244,7 +244,7 @@ METHOD(public_key_t, get_fingerprint, bool,
                return TRUE;
        }
        success = bliss_public_key_fingerprint(this->set->oid, this->A,
-                                                                                  this->set->n, type, fp);
+                                                                                  this->set, type, fp);
        lib->encoding->cache(lib->encoding, type, this, *fp);
 
        return success;
@@ -361,21 +361,10 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args)
                                break;
                        }
                        case BLISS_SUBJECT_PUBLIC_KEY:
-                               if (object.len > 0 && *object.ptr == 0x00)
-                               {
-                                       /* skip initial bit string octet defining 0 unused bits */
-                                       object = chunk_skip(object, 1);
-                               }
-                               if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
-                                               parser->get_level(parser)+1, "blissPublicKey"))
+                               if (!bliss_public_key_from_asn1(object, this->set, &this->A))
                                {
                                        goto end;
                                }
-                               if (object.len != 2*this->set->n)
-                               {
-                                       goto end;
-                               }
-                               this->A = bliss_public_key_from_asn1(object, this->set->n);
                                break;
                }
        }
@@ -395,42 +384,51 @@ end:
 /**
  * See header.
  */
-uint32_t* bliss_public_key_from_asn1(chunk_t object, int n)
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+                                                               uint32_t **pubkey)
 {
-       uint32_t *pubkey;
-       uint16_t coeff;
-       u_char *pos;
+       bliss_bitpacker_t *packer;
+       uint16_t coefficient;
        int i;
 
-       pubkey = malloc(n * sizeof(uint32_t));
-       pos = object.ptr;
+       /* skip initial bit string octet defining unused bits */
+       object = chunk_skip(object, 1);
 
-       for (i = 0; i < n; i++)
+       if (8 * object.len < set->n * set->q_bits)
        {
-               coeff = untoh16(pos);
-               pubkey[i] = (uint32_t)coeff;
-               pos += 2;
+               return FALSE;
        }
+       *pubkey = malloc(set->n * sizeof(uint32_t));
 
-       return pubkey;
+       packer = bliss_bitpacker_create_from_data(object);
+
+       for (i = 0; i < set->n; i++)
+       {
+               packer->read_bits(packer, &coefficient, set->q_bits);
+               (*pubkey)[i] = (uint32_t)coefficient;
+       }
+       packer->destroy(packer);
+
+       return TRUE;
 }
 
 /**
  * See header.
  */
-chunk_t bliss_public_key_encode(uint32_t *pubkey, int n)
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set)
 {
-       u_char *pos;
+       bliss_bitpacker_t *packer;
        chunk_t encoding;
        int i;
 
-       pos = asn1_build_object(&encoding, ASN1_OCTET_STRING, 2 * n);
+       packer = bliss_bitpacker_create(set->n * set->q_bits);
 
-       for (i = 0; i < n; i++)
+       for (i = 0; i < set->n; i++)
        {
-               htoun16(pos, (uint16_t)pubkey[i]);
-               pos += 2;
+               packer->write_bits(packer, pubkey[i], set->q_bits);
        }
+       encoding = packer->extract_buf(packer);
+       packer->destroy(packer);
 
        return encoding;
 }
@@ -438,11 +436,12 @@ chunk_t bliss_public_key_encode(uint32_t *pubkey, int n)
 /**
  * See header.
  */
-chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n)
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+                                                                        bliss_param_set_t *set)
 {
        chunk_t encoding, pubkey_encoding;
 
-       pubkey_encoding = bliss_public_key_encode(pubkey, n);
+       pubkey_encoding = bliss_public_key_encode(pubkey, set);
 
        encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
                                        asn1_wrap(ASN1_SEQUENCE, "mm",
@@ -456,7 +455,8 @@ chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n)
 /**
  * See header.
  */
-bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n,
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+                                                                 bliss_param_set_t *set,
                                                                  cred_encoding_type_t type, chunk_t *fp)
 {
        hasher_t *hasher;
@@ -465,10 +465,10 @@ bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n,
        switch (type)
        {
                case KEYID_PUBKEY_SHA1:
-                       key = bliss_public_key_encode(pubkey, n);
+                       key = bliss_public_key_encode(pubkey, set);
                        break;
                case KEYID_PUBKEY_INFO_SHA1:
-                       key = bliss_public_key_info_encode(oid, pubkey, n);
+                       key = bliss_public_key_info_encode(oid, pubkey, set);
                        break;
                default:
                        return FALSE;
index aa871b5edea9dc515c37e42e03d8c2d8d96c1fb7..9ffd3177781cc31db9f38f5dfc32d83d96c360ad 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef BLISS_PUBLIC_KEY_H_
 #define BLISS_PUBLIC_KEY_H_
 
+#include "bliss_param_set.h"
+
 #include <credentials/builder.h>
 #include <credentials/cred_encoding.h>
 #include <credentials/keys/public_key.h>
@@ -52,44 +54,48 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args);
 /* The following functions are shared with the bliss_private_key class */
 
 /**
- * Parse an ASN.1 OCTET STRING into an array of public key coefficients
+ * Parse an ASN.1 BIT STRING into an array of public key coefficients
  *
- * @param object       ASN.1 encoded subjectPublicKey
- * @param n                    number of public key coefficients
- * @result                     coefficients of public key vector
+ * @param data         packed subjectPublicKey
+ * @param set          BLISS parameter set for public key vector
+ * @param pubkey       coefficients of public key vector
+ * @return                     TRUE if parsing successful
  */
-uint32_t* bliss_public_key_from_asn1(chunk_t object, int n);
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+                                                               uint32_t **pubkey);
 
 /**
  * Encode a raw BLISS subjectPublicKey in ASN.1 DER format
  *
  * @param                      coefficients of public key vector
- * @param n                    number of public key coefficients
+ * @param set          BLISS parameter set for the public key vector
  * @result                     ASN.1 encoded subjectPublicKey
  */
-chunk_t bliss_public_key_encode(uint32_t *pubkey, int n);
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set);
 
 /**
  * Encode a BLISS subjectPublicKeyInfo record in ASN.1 DER format
  *
  * @param oid          BLISS public key type OID
  * @param pubkey       coefficients of public key vector
- * @param n                    number of public key coefficients
+ * @param n                    BLISS parameter set for the public key vector
  * @result                     ASN.1 encoded subjectPublicKeyInfo record
  */
-chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n);
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+                                                                        bliss_param_set_t *set);
 
 /**
  * Generate a BLISS public key fingerprint
  *
  * @param oid          BLISS public key type OID
  * @param pubkey       coefficients of public key vector
- * @param n                    number of public key coefficients
+ * @param n                    BLISS parameter set for the public key vector
  * @param type         type of fingerprint to be generated
  * @param fp           generated fingerprint (must be freed by caller)
  * @result                     TRUE if generation was successful
  */
-bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n,
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+                                                                 bliss_param_set_t *set,
                                                                  cred_encoding_type_t type, chunk_t *fp);
 
 #endif /** BLISS_PUBLIC_KEY_H_ @}*/