예제 #1
0
/**
 * @brief Calculate the Endpoint Secondary Signing Key (ESSK)
 *
 * @param y2 A pointer to the Y2 term used by all
 * @param essk A pointer to the output ESSK variable
 * @param ims_sample_compatibility If true, generate IMS values that are
 *        compatible with the original (incorrect) 100 sample values sent
 *        to Toshiba 2016/01/14. If false, generate the IMS value using
 *        the correct form.
 */
void calc_essk(uint8_t * y2, mcl_octet * essk,
               bool ims_sample_compatibility) {
    uint8_t z2[SHA256_HASH_DIGEST_SIZE];
    uint8_t scratch_hash[SHA256_HASH_DIGEST_SIZE];
    int status;


    if (ims_sample_compatibility) {
        /**
         *  Y2 = sha256(IMS[0:31] xor copy(0x5a, 32))  // (provided)
         *  EPSK[0:31] = sha256(Y2 || copy(0x01, 32))
         */
        sha256_concat(essk->val, y2, 0x01, 32);
    } else {
        /**
         *  Y2 = sha256(IMS[0:31] xor copy(0x5a, 32))  // (provided)
         *  Z2 = sha256(Y2 || copy(0x02, 32))
         *  ESSK[0:31] = sha256(Z2 || copy(0x01, 32))
         */
        sha256_concat(z2, y2, 0x02, 32);
        sha256_concat(scratch_hash, z2, 0x01, 32);

        memcpy(essk->val, scratch_hash, SHA256_HASH_DIGEST_SIZE);
        essk->len = SHA256_HASH_DIGEST_SIZE;
    }
    essk->len = SHA256_HASH_DIGEST_SIZE;
#ifdef IMS_DEBUGMSG
    display_binary_data(essk->val, essk->len, true, "essk ");
#endif
}
예제 #2
0
/**
 * @brief Calculate the Endpoint Primary Signing Key (EPSK)
 *
 * @param y2 A pointer to the Y2 term used by all
 * @param epsk A pointer to the output EPSK variable
 */
void calc_epsk(uint8_t * y2, mcl_octet * epsk) {
    uint8_t z1[SHA256_HASH_DIGEST_SIZE];
    uint8_t scratch_hash[SHA256_HASH_DIGEST_SIZE];
    int status;

    /**
     *  Y2 = sha256(IMS[0:31] xor copy(0x5a, 32))  // (provided)
     *  Z1 = sha256(Y2 || copy(0x01, 32))
     *  EPSK[0:31] = sha256(Z1 || copy(0x01, 32))
     *  EPSK[32:55] = sha256(Z1 || copy(0x02, 32))[0:23]
     */
    sha256_concat(z1, y2, 0x01, 32);

    sha256_concat(scratch_hash, z1, 0x01, 32);
    memcpy(&epsk->val[0], scratch_hash, SHA256_HASH_DIGEST_SIZE);

    sha256_concat(scratch_hash, z1, 0x02, 32);
    memcpy(&epsk->val[SHA256_HASH_DIGEST_SIZE],
           scratch_hash,
           (EPSK_SIZE - SHA256_HASH_DIGEST_SIZE));
    epsk->len = EPSK_SIZE;
#ifdef IMS_DEBUGMSG
    display_binary_data(epsk->val, epsk->len, true, "epsk ");
#endif
}
예제 #3
0
static void calculate_ergs(uint8_t *y2, uint8_t *ergs) {
    uint8_t z5[SHA256_HASH_DIGEST_SIZE];

    /* Z5 = sha256(Y2 || copy(0x05, 32)) */
    sha256_concat(y2, 0x05, 32, z5);

    /* ERGS = sha256(Z5 || copy(0x01, 32)) */
    sha256_concat(z5, 0x01, 32, ergs);
}
예제 #4
0
static void calculate_epck(uint8_t *y2, uint8_t *epck) {
    uint8_t z4[SHA256_HASH_DIGEST_SIZE];

    /* Z4 = sha256(Y2 || copy(0x04, 32)) */
    sha256_concat(y2, 0x04, 32, z4);

    /* EPCK = sha256(Z4 || copy(0x01, 32)) */
    sha256_concat(z4, 0x01, 32, epck);
}
예제 #5
0
static void calculate_essk(uint8_t *y2, uint8_t *essk) {
    uint8_t z2[SHA256_HASH_DIGEST_SIZE];

    /* Z2 = sha256(Y2 || copy(0x02, 32)) */
    sha256_concat(y2, 0x02, 32, z2);

    /* ESSK[0:31] = sha256(Z2 || copy(0x01, 32)) */
    sha256_concat(z2, 0x01, 32, essk);
}
예제 #6
0
static void calculate_epsk(uint8_t *y2, uint8_t *epsk) {
    uint8_t z1[SHA256_HASH_DIGEST_SIZE];
    uint8_t t[SHA256_HASH_DIGEST_SIZE];

    /* Z1 = sha256(Y2 || copy(0x01, 32)) */
    sha256_concat(y2, 0x01, 32, z1);

    /* EPSK[0:31] = sha256(Z1 || copy(0x01, 32)) */
    sha256_concat(z1, 0x01, 32, epsk);

    /* EPSK[32:51] = sha256(Z1 || copy(0x02, 32))[0:19] */
    sha256_concat(z1, 0x02, 32, t);
    memcpy(&epsk[32], t, 24);
}
예제 #7
0
static void calculate_errk(uint8_t *y2, uint8_t *ims, uint8_t *errk_n) {
    uint8_t z3[SHA256_HASH_DIGEST_SIZE];
    MCL_rsa_public_key_RSA2048 pub;
    MCL_rsa_private_key_RSA2048 priv;
    uint8_t errk_p[RSA2048_PUBLIC_KEY_SIZE/2];
    uint8_t errk_q[RSA2048_PUBLIC_KEY_SIZE/2];

    /* Z3 = sha256(Y2 || copy(0x03, 32)) */
    sha256_concat(y2, 0x03, 32, z3);

    /**
     * ERRK_P[0:31] = sha256(Z3 || copy(0x01, 32))
     * ERRK_P[32:63] = sha256(Z3 || copy(0x02, 32))
     * ERRK_P[64:95] = sha256(Z3 || copy(0x03, 32))
     * ERRK_P[96:127] = sha256(Z3 || copy(0x04, 32))
     * ERRK_P[0] |= 0x03
     */
    sha256_concat(z3, 0x01, 32, &errk_p[0]);
    sha256_concat(z3, 0x02, 32, &errk_p[32]);
    sha256_concat(z3, 0x03, 32, &errk_p[64]);
    sha256_concat(z3, 0x04, 32, &errk_p[96]);
    errk_p[0] |= ERRK_ALIAS_MOD_BITS;

    bytes_to_MCL_FF(errk_p, RSA2048_PUBLIC_KEY_SIZE/2, priv.p, MCL_FFLEN1/2);

    /**
     * ERRK_Q[0:31] = sha256(Z3 || copy(0x05, 32))
     * ERRK_Q[32:63] = sha256(Z3 || copy(0x06, 32))
     * ERRK_Q[64:95] = sha256(Z3 || copy(0x07, 32))
     * ERRK_Q[96:127] = sha256(Z3 || copy(0x08, 32))
     * ERRK_Q[0] |= 0x03
     */
    sha256_concat(z3, 0x05, 32, &errk_q[0]);
    sha256_concat(z3, 0x06, 32, &errk_q[32]);
    sha256_concat(z3, 0x07, 32, &errk_q[64]);
    sha256_concat(z3, 0x08, 32, &errk_q[96]);
    errk_q[0] |= ERRK_ALIAS_MOD_BITS;

    bytes_to_MCL_FF(errk_q, RSA2048_PUBLIC_KEY_SIZE/2, priv.q, MCL_FFLEN1/2);

    /* ERRK_P += 4 * IMS[34:32] / 4096 */
    /* ERRK_Q += 4 * IMS[34:32] % 4096 */
    uint32_t alias_ims = (*((uint32_t *)&ims[32]) & 0x00FFFFFF);
    MCL_FF_inc_C448(priv.p,
                    (alias_ims >> 12) << ERRK_ALIAS_MOD_SHIFT,
                    MCL_FFLEN1/2);
    MCL_FF_inc_C448(priv.q,
                    (alias_ims & 0xFFF) << ERRK_ALIAS_MOD_SHIFT,
                    MCL_FFLEN1/2);

#if DBG_SECRET_KEY_MSG
    ff_dump(priv.p, MCL_FFLEN1/2, "p ");
    ff_dump(priv.q, MCL_FFLEN1/2, "q ");
#endif

    /* ERPK_MOD = ERRK_Q * ERRK_P */
    MCL_FF_mul_C448(pub.n, priv.p, priv.q, MCL_FFLEN1/2);

#if DBG_SECRET_KEY_MSG
    ff_dump(pub.n, MCL_FFLEN1, "n ");
#endif

    MCL_FF_to_bytes(pub.n,
                    MCL_FFLEN1,
                    errk_n,
                    RSA2048_PUBLIC_KEY_SIZE);
    /* ERPK_E = 65537 */
    pub.e = 65537;

    /* TBD: do we even need the private key on the bridge side? */
    /* ERRK_D = RSA_secret(ERRK_P, ERRK_Q, ERPK_E) */
}
예제 #8
0
/**
 * @brief Calculate the Endpoint Rsa pRivate Key (ERRK) P & Q factors
 *
 * Calculates the ERRK_P & ERRK_Q, up to and including the bias-to-odd
 * step (i.e., that which can be extracted from IMS[0:31]).
 *
 *
 * @param y2 A pointer to the Y2 term used by all
 * @param ims A pointer to the ims (the upper 3 bytes will be modified)
 * @param erpk_p A pointer to a buffer to store the ERRK P coefficient
 * @param errk_q A pointer to a buffer to store the ERPK Q coefficient
 * @param ims_sample_compatibility If true, generate IMS values that are
 *        compatible with the original (incorrect) 100 sample values sent
 *        to Toshiba 2016/01/14. If false, generate the IMS value using
 *        the correct form.
 *
 * @returns Zero if successful, errno otherwise.
 */
void calc_errk_pq_bias_odd(uint8_t * y2,
                           uint8_t * ims,
                           mcl_octet * errk_p,
                           mcl_octet * errk_q,
                           bool ims_sample_compatibility) {
    int status = 0;
    uint8_t z3[SHA256_HASH_DIGEST_SIZE];
    uint8_t odd_mod_bitmask;
    int pq_len;

    /**
     * Define constants based on compatibility with the original 100 IMS samples
     * delivered to Toshiba or the correct production form.
     */
    if (ims_sample_compatibility) {
        odd_mod_bitmask = ODD_3_MOD_4_BITMASK;
        pq_len = SHA256_HASH_DIGEST_SIZE;
    } else {
        odd_mod_bitmask = ODD_MOD_BITMASK(ODD_MOD_PRODUCTION);
        pq_len = ERRK_PQ_SIZE;
    }

    /**
     *  Y2 = sha256(IMS[0:31] xor copy(0x5a, 32))  // (provided)
     *  Z3 = sha256(Y2 || copy(0x03, 32))
     *   :
     */
    sha256_concat(z3, y2, 0x03, 32);

    /**
     *   :
     *  ERRK_P[0:31] = sha256(Z3 || copy(0x01, 32))
     *  ERRK_P[32:63] = sha256(Z3 || copy(0x02, 32))
     *  ERRK_P[64:95] = sha256(Z3 || copy(0x03, 32))
     *  ERRK_P[96:127] = sha256(Z3 || copy(0x41, 32))
     *   :
     */
    sha256_concat(&errk_p->val[0],  z3, 0x01, 32);
    sha256_concat(&errk_p->val[32], z3, 0x02, 32);
    sha256_concat(&errk_p->val[64], z3, 0x03, 32);
    sha256_concat(&errk_p->val[96], z3, 0x04, 32);
    errk_p->len = pq_len;

    /**
     *   :
     *  ERRK_Q[0:31] = sha256(Z3 || copy(0x05, 32))
     *  ERRK_Q[32:63] = sha256(Z3 || copy(0x06, 32))
     *  ERRK_Q[64:95] = sha256(Z3 || copy(0x07, 32))
     *  ERRK_Q[96:127] = sha256(Z3 || copy(0x8, 32))
     *   :
     */
    sha256_concat(&errk_q->val[0],  z3, 0x05, 32);
    sha256_concat(&errk_q->val[32], z3, 0x06, 32);
    sha256_concat(&errk_q->val[64], z3, 0x07, 32);
    sha256_concat(&errk_q->val[96], z3, 0x08, 32);
    errk_q->len = pq_len;

    /* Force P, Q to be suitably odd */
    errk_p->val[0] |= odd_mod_bitmask;
    errk_q->val[0] |= odd_mod_bitmask;
}