Ejemplo n.º 1
0
int dslink_handshake_store_key_pair(mbedtls_ecdh_context *key,
                                    char *buf, size_t bufLen) {
    unsigned char dEnc[45];
    unsigned char qEnc[90];
    size_t dEncLen = 0;
    size_t qEncLen = 0;
    {
        unsigned char dBin[33];
        if ((errno = mbedtls_mpi_write_binary(&key->d,
                                              dBin, sizeof(dBin))) != 0) {
            return DSLINK_CRYPT_KEY_ENCODE_ERR;
        }

        if (dslink_base64_url_encode(dEnc, sizeof(dEnc), &dEncLen,
                                     dBin, sizeof(dBin)) != 0) {
            return DSLINK_CRYPT_BASE64_URL_ENCODE_ERR;
        }
    }

    {
        unsigned char qBin[65];
        if ((errno = mbedtls_ecp_point_write_binary(&key->grp,
                                                    &key->Q,
                                                    MBEDTLS_ECP_PF_UNCOMPRESSED,
                                                    &qEncLen, qBin,
                                                    sizeof(qBin))) != 0) {
            return DSLINK_CRYPT_KEY_ENCODE_ERR;
        }

        if (dslink_base64_url_encode(qEnc, sizeof(qEnc),
                                     &qEncLen, qBin, qEncLen) != 0) {
            return DSLINK_CRYPT_BASE64_URL_ENCODE_ERR;
        }
    }

    size_t bufSize;
    {
        // Add additional size for the space separator and null terminator
        bufSize = dEncLen + qEncLen + 1;
        if (bufLen < bufSize) {
            return DSLINK_BUF_TOO_SMALL;
        }
        memcpy(buf, dEnc, dEncLen);
        memset(buf + dEncLen, ' ', 1);
        memcpy(buf + dEncLen + 1, qEnc, qEncLen);
        *(buf + bufSize) = '\0';
    }

    return (int) bufSize;
}
Ejemplo n.º 2
0
/*
 * EC public key is an EC point
 */
static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
                               mbedtls_ecp_keypair *ec )
{
    int ret;
    size_t len = 0;
    unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];

    if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q,
                MBEDTLS_ECP_PF_UNCOMPRESSED,
                &len, buf, sizeof( buf ) ) ) != 0 )
    {
        return( ret );
    }

    if( *p - start < (int) len )
        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );

    *p -= len;
    memcpy( *p, buf, len );

    return( (int) len );
}
Ejemplo n.º 3
0
//need to normalize the coordinates
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
                  const unsigned char *buf, size_t blen,
                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
{
    int ret = 0;
    CRYSError_t CrysRet = CRYS_OK;
    void* pHeap = NULL;
    size_t heapSize = 0;
    uint8_t * pSignature = NULL;
    CRYS_ECPKI_HASH_OpMode_t hash_mode = message_size_to_hash_mode( blen );
    size_t temp_size = 0;
    uint32_t signature_size = ( ( grp->nbits + 7 ) / 8 ) * 2;
    const CRYS_ECPKI_Domain_t*  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) );

#if SIZE_MAX > UINT_MAX
    if( blen > 0xFFFFFFFF )
    {
        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
    }
#endif

    if ( pDomain )
    {
        uint8_t temp_buf[ 2*MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};

        cc_ecc_ws_verify_params_t* verifyParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_verify_params_t) );
        if ( verifyParams == NULL)
            return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
        pHeap = verifyParams;
        heapSize = sizeof(cc_ecc_ws_verify_params_t);

        pSignature = mbedtls_calloc( 1, signature_size );
        if ( pSignature == NULL)
        {
            ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
            goto cleanup;
        }

        MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
                                        &temp_size, temp_buf, sizeof(temp_buf) ) );

        CrysRet = CRYS_ECPKI_BuildPublKey(pDomain, temp_buf, temp_size, &verifyParams->pubKey);
        if( CrysRet != CRYS_OK )
        {
            ret = convert_CrysError_to_mbedtls_err( CrysRet );
            goto cleanup;
        }

        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( r, pSignature, ( ( grp->nbits + 7 ) / 8 )  ) );
        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( s, pSignature + ( ( grp->nbits + 7 ) / 8 ), ( ( grp->nbits + 7 ) / 8 ) ) );
        CrysRet =  CRYS_ECDSA_Verify ( &verifyParams->verifyContext,
                                       &verifyParams->pubKey,
                                       hash_mode,
                                       pSignature,
                                       signature_size,
                                       (uint8_t*)buf,
                                       blen );
        if( CrysRet != CRYS_OK )
        {
            ret = convert_CrysError_to_mbedtls_err( CrysRet );
            goto cleanup;
        }
    }
    else
        ret =  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;

cleanup:

    if( pHeap )
    {
        mbedtls_zeroize( pHeap, heapSize );
        mbedtls_free( pHeap );
    }

    if( pSignature )
    {
        mbedtls_zeroize( pSignature, signature_size );
        mbedtls_free( pSignature );

    }

    return ret;
}
Ejemplo n.º 4
0
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
                         const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng )
{
    int ret;
    void* pHeap = NULL;
    size_t   heapSize = 0;

    size_t   public_key_size = (grp->nbits+7)/8 ;
    const CRYS_ECPKI_Domain_t*  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) );
    uint32_t secret_size =  ( ( grp->nbits + 7 ) / 8 ) ;
    const uint32_t secret_size_in_heap = secret_size;
    uint8_t* secret = mbedtls_calloc( 1, secret_size_in_heap );
    if ( secret == NULL )
        return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );

    /*
     * Make sure Q is a valid pubkey before using it
     */
    MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
    if ( pDomain )
    {
        uint8_t  temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
        cc_ecc_ws_comp_shared_params_t* ecdhParams =  mbedtls_calloc( 1, sizeof(cc_ecc_ws_comp_shared_params_t) );

        if ( ecdhParams == NULL )
        {
            ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
            goto cleanup;
        }

        pHeap = ecdhParams;
        heapSize = sizeof(cc_ecc_ws_comp_shared_params_t);


        MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
                                                &public_key_size, temp_buf, sizeof(temp_buf) ) );

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPublKey( pDomain, temp_buf, public_key_size,
                                                                         &ecdhParams->pubKey ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }

        memset ( temp_buf, 0, sizeof(temp_buf)  );

        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) );

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPrivKey( pDomain,
                                                                         temp_buf,
                                                                         mbedtls_mpi_size( d ),
                                                                         &ecdhParams->privKey ) );
        mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECDH_SVDP_DH( &ecdhParams->pubKey, &ecdhParams->privKey,
                                                                   secret, &secret_size,
                                                                   &ecdhParams->ecdhTempData ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }
    }
    else if ( grp->id ==  MBEDTLS_ECP_DP_CURVE25519 )
    {
        cc_ecc_25519_comp_shared_params_t* ecdhParams =  mbedtls_calloc( 1, sizeof(cc_ecc_25519_comp_shared_params_t) );
        if ( ecdhParams == NULL )
        {
            ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
            goto cleanup;
        }

        pHeap = ecdhParams;
        heapSize = sizeof(cc_ecc_25519_comp_shared_params_t);


        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, ecdhParams->privKey, mbedtls_mpi_size( d ) ) ) ;
        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &Q->X, ecdhParams->pubKey, public_key_size ) );

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_Scalarmult( secret, ( size_t* )&secret_size,
                                                                        ecdhParams->privKey, CURVE_25519_KEY_SIZE ,
                                                                        ecdhParams->pubKey, CURVE_25519_KEY_SIZE ,
                                                                        &ecdhParams->kgTempData ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }
    }
    else
    {
        ret =  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
        goto cleanup;
    }

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( z, secret, secret_size ) );

cleanup:

    if ( pHeap )
    {
        mbedtls_zeroize( pHeap, heapSize );
        mbedtls_free ( pHeap );
    }

    if ( secret )
    {
        mbedtls_zeroize( secret, secret_size_in_heap );
        mbedtls_free ( secret );
    }

    return ( ret );
}
Ejemplo n.º 5
0
int dslink_handshake_generate(Url *url,
                              mbedtls_ecdh_context *key,
                              const char *name,
                              uint8_t isRequester,
                              uint8_t isResponder,
                              json_t **handshake,
                              char **dsId) {
    *handshake = NULL;
    Socket *sock = NULL;
    char *resp = NULL;
    char *body = NULL;
    int ret = 0;

    unsigned char pubKeyBin[65];
    size_t pubKeyBinLen = 0;

    unsigned char pubKey[90];
    size_t pubKeyLen = 0;

    if ((errno = mbedtls_ecp_point_write_binary(&key->grp,
                                                &key->Q,
                                                MBEDTLS_ECP_PF_UNCOMPRESSED,
                                                &pubKeyBinLen, pubKeyBin,
                                                sizeof(pubKeyBin))) != 0) {
        ret = DSLINK_CRYPT_KEY_ENCODE_ERR;
        goto exit;
    }

    if ((errno = dslink_base64_url_encode(pubKey,
                                          sizeof(pubKey),
                                          &pubKeyLen,
                                          pubKeyBin,
                                          pubKeyBinLen)) != 0) {
        ret = DSLINK_CRYPT_BASE64_URL_ENCODE_ERR;
        goto exit;
    }

    { // Generate dsId
        unsigned char sha[32];
        mbedtls_sha256(pubKeyBin, pubKeyBinLen, sha, 0);

        unsigned char tmp[45];
        size_t tmpLen = 0;
        if ((errno = dslink_base64_url_encode((unsigned char *) tmp,
                                              sizeof(tmp),
                                              &tmpLen,
                                              sha,
                                              sizeof(sha))) != 0) {
            ret = DSLINK_CRYPT_BASE64_URL_ENCODE_ERR;
            goto exit;
        }

        size_t nameLen = strlen(name);
        *dsId = malloc(nameLen + tmpLen + 2);
        if (!(*dsId)) {
            ret = DSLINK_ALLOC_ERR;
            goto exit;
        }
        memcpy(*dsId, name, nameLen);
        *(*dsId + nameLen) = '-';
        memcpy((*dsId + nameLen + 1), (char *) tmp, tmpLen);
        *(*dsId + nameLen + tmpLen + 1) = '\0';
    }

    { // Create the request body
        json_t *obj = json_object();
        if (!obj) {
            ret = DSLINK_ALLOC_ERR;
            goto exit;
        }

        json_object_set_new(obj, "publicKey", json_string((char *) pubKey));
        json_object_set_new(obj, "isRequester", json_boolean(isRequester));
        json_object_set_new(obj, "isResponder", json_boolean(isResponder));
        json_object_set_new(obj, "version", json_string("1.1.2"));
        body = json_dumps(obj, JSON_INDENT(2));
        json_delete(obj);
        if (!body) {
            ret = DSLINK_ALLOC_ERR;
            goto exit;
        }
    }

    char req[512];
    size_t reqLen;
    {
        char uri[128];
        snprintf(uri, sizeof(uri), "%s?dsId=%s", url->uri, *dsId);
        reqLen = snprintf(req, sizeof(req), DSLINK_POST_REQ, uri, url->host,
                          url->port, (int) strlen(body), body);
    }

    if ((ret = dslink_socket_connect(&sock, url->host,
                                     url->port, url->secure)) != 0) {
        goto exit;
    }

    dslink_socket_write(sock, req, reqLen);

    int respLen = 0;
    while (1) {
        char buf[1024];
        int read = dslink_socket_read(sock, buf, sizeof(buf) - 1);
        if (read <= 0) {
            break;
        }
        if (resp == NULL) {
            resp = malloc((size_t) read + 1);
            if (!resp) {
                ret = DSLINK_ALLOC_ERR;
                goto exit;
            }
            respLen = read;
            memcpy(resp, buf, read);
            *(resp + respLen) = '\0';
        } else {
            char *tmp = realloc(resp, (size_t) respLen + read + 1);
            if (!tmp) {
                free(resp);
                ret = DSLINK_ALLOC_ERR;
                goto exit;
            }
            resp = tmp;
            memcpy(resp + respLen, buf, read);
            respLen += read;
            *(resp + respLen) = '\0';
        }
    }

    if (!resp) {
        ret = DSLINK_HANDSHAKE_NO_RESPONSE;
        goto exit;
    }

    char *index = strstr(resp, "401 Unauthorized");
    if (index) {
        ret = DSLINK_HANDSHAKE_UNAUTHORIZED;
        goto exit;
    }

    index = strchr(resp, '{');
    if (!index) {
        ret = DSLINK_HANDSHAKE_INVALID_RESPONSE;
        goto exit;
    }

    char *json = index;
    index = strrchr(json, '}');
    if (!index) {
        ret = DSLINK_HANDSHAKE_INVALID_RESPONSE;
        goto exit;
    }
    *(index + 1) = '\0';

    json_error_t jsonErr;
    *handshake = json_loads(json, 0, &jsonErr);
    if (!(*handshake)) {
        ret = DSLINK_ALLOC_ERR;
        goto exit;
    }
    const char *id = json_string_value(json_object_get(*handshake, "id"));
    if (id) {
        free(*dsId);
        size_t size = strlen(id) + 1;
        *dsId = malloc(size);
        if (!(*dsId)) {
            ret = DSLINK_ALLOC_ERR;
            json_delete(*handshake);
            *handshake = NULL;
            goto exit;
        }
        memcpy(*dsId, id, size);
    }

exit:
    DSLINK_CHECKED_EXEC(free, body);
    DSLINK_CHECKED_EXEC(free, resp);
    DSLINK_CHECKED_EXEC(dslink_socket_close, sock);
    return ret;
}