efx_lic.c revision 49ef7e0638c8b771d8a136eae78b1c0f99acc8e0
/*
* Copyright (c) 2009-2015 Solarflare Communications Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the FreeBSD Project.
*/
#include "efx.h"
#include "efx_impl.h"
#include "ef10_tlv_layout.h"
);
);
);
);
);
);
);
);
);
#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
#if EFSYS_OPT_SIENA
static __checkReturn efx_rc_t
static __checkReturn efx_rc_t
static const efx_lic_ops_t __efx_lic_v1_ops = {
efx_mcdi_fc_license_update_license, /* elo_update_licenses */
efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */
NULL, /* elo_app_state */
NULL, /* elo_get_id */
efx_lic_v1v2_find_start, /* elo_find_start */
efx_lic_v1v2_find_end, /* elo_find_end */
efx_lic_v1v2_find_key, /* elo_find_key */
efx_lic_v1v2_validate_key, /* elo_validate_key */
efx_lic_v1v2_read_key, /* elo_read_key */
efx_lic_v1v2_write_key, /* elo_write_key */
efx_lic_v1v2_delete_key, /* elo_delete_key */
efx_lic_v1v2_create_partition, /* elo_create_partition */
efx_lic_v1v2_finish_partition, /* elo_finish_partition */
};
#endif /* EFSYS_OPT_SIENA */
static __checkReturn efx_rc_t
static __checkReturn efx_rc_t
static __checkReturn efx_rc_t
static const efx_lic_ops_t __efx_lic_v2_ops = {
efx_mcdi_licensing_update_licenses, /* elo_update_licenses */
efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */
efx_mcdi_licensed_app_state, /* elo_app_state */
NULL, /* elo_get_id */
efx_lic_v1v2_find_start, /* elo_find_start */
efx_lic_v1v2_find_end, /* elo_find_end */
efx_lic_v1v2_find_key, /* elo_find_key */
efx_lic_v1v2_validate_key, /* elo_validate_key */
efx_lic_v1v2_read_key, /* elo_read_key */
efx_lic_v1v2_write_key, /* elo_write_key */
efx_lic_v1v2_delete_key, /* elo_delete_key */
efx_lic_v1v2_create_partition, /* elo_create_partition */
efx_lic_v1v2_finish_partition, /* elo_finish_partition */
};
#endif /* EFSYS_OPT_HUNTINGTON */
static __checkReturn efx_rc_t
static __checkReturn efx_rc_t
static __checkReturn efx_rc_t
static __checkReturn efx_rc_t
);
);
);
);
);
);
);
);
);
static const efx_lic_ops_t __efx_lic_v3_ops = {
efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */
efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */
efx_mcdi_licensing_v3_app_state, /* elo_app_state */
efx_mcdi_licensing_v3_get_id, /* elo_get_id */
efx_lic_v3_find_start, /* elo_find_start*/
efx_lic_v3_find_end, /* elo_find_end */
efx_lic_v3_find_key, /* elo_find_key */
efx_lic_v3_validate_key, /* elo_validate_key */
efx_lic_v3_read_key, /* elo_read_key */
efx_lic_v3_write_key, /* elo_write_key */
efx_lic_v3_delete_key, /* elo_delete_key */
efx_lic_v3_create_partition, /* elo_create_partition */
efx_lic_v3_finish_partition, /* elo_finish_partition */
};
#endif /* EFSYS_OPT_MEDFORD */
/* V1 Licensing - used in Siena Modena only */
#if EFSYS_OPT_SIENA
static __checkReturn efx_rc_t
{
req.emr_out_length = 0;
goto fail1;
}
if (req.emr_out_length_used != 0) {
goto fail2;
}
return (0);
return (rc);
}
static __checkReturn efx_rc_t
{
goto fail1;
}
goto fail2;
}
eksp->eks_invalid =
eksp->eks_unverifiable = 0;
eksp->eks_wrong_node = 0;
eksp->eks_licensed_apps_lo = 0;
eksp->eks_licensed_apps_hi = 0;
eksp->eks_licensed_features_lo = 0;
eksp->eks_licensed_features_hi = 0;
return (0);
return (rc);
}
#endif /* EFSYS_OPT_SIENA */
/* V1 and V2 Partition format - based on a 16-bit TLV format */
/*
* Length (L): 16bit - value length in bytes
* Value (V): L bytes - payload
*/
#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX (256)
)
{
*startp = 0;
return (0);
}
)
{
return (0);
}
)
{
goto fail1;
if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
(tlv_type == 0 && tlv_length == 0)) {
} else {
}
return (found);
return (B_FALSE);
}
)
{
if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
goto fail1;
}
goto fail2;
}
if (tlv_type == 0) {
goto fail3;
}
goto fail4;
}
return (B_TRUE);
return (B_FALSE);
}
)
{
if (key_max_size < length) {
goto fail1;
}
return (0);
return (rc);
}
)
{
// Ensure space for terminator remains
goto fail1;
}
return (0);
return (rc);
}
)
{
// Shift everything after the key down
return (0);
}
)
{
// Write terminator
return (0);
}
)
{
return (0);
}
#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
/* V2 Licensing - used by Huntington family only. See SF-113611-TC */
static __checkReturn efx_rc_t
{
/* V2 licensing supports 32bit app id only */
if ((app_id >> 32) != 0) {
goto fail1;
}
app_id & 0xffffffff);
goto fail2;
}
goto fail3;
}
} else {
}
return (0);
return (rc);
}
static __checkReturn efx_rc_t
{
req.emr_out_length = 0;
goto fail1;
}
if (req.emr_out_length_used != 0) {
goto fail2;
}
return (0);
return (rc);
}
static __checkReturn efx_rc_t
{
goto fail1;
}
goto fail2;
}
eksp->eks_invalid =
eksp->eks_licensed_apps_lo = 0;
eksp->eks_licensed_apps_hi = 0;
eksp->eks_licensed_features_lo = 0;
eksp->eks_licensed_features_hi = 0;
return (0);
return (rc);
}
#endif /* EFSYS_OPT_HUNTINGTON */
/* V3 Licensing - used starting from Medford family. See SF-114884-SW */
static __checkReturn efx_rc_t
{
req.emr_out_length = 0;
goto fail1;
}
return (0);
return (rc);
}
static __checkReturn efx_rc_t
{
goto fail1;
}
goto fail2;
}
eksp->eks_invalid =
eksp->eks_blacklisted = 0;
return (0);
return (rc);
}
static __checkReturn efx_rc_t
{
app_id & 0xffffffff);
app_id >> 32);
goto fail1;
}
goto fail2;
}
} else {
}
return (0);
return (rc);
}
static __checkReturn efx_rc_t
{
/* Request id type and length only */
} else {
/* Request full buffer */
}
goto fail1;
}
goto fail2;
}
/* modify length requirements to indicate to caller the extra buffering
** needed to read the complete output.
*/
} else {
/* Shift ID down to start of buffer */
*lengthp);
}
return (0);
return (rc);
}
/* V3 format uses Huntington TLV format partition. See SF-108797-SW */
#define EFX_LICENSE_V3_KEY_LENGTH_MIN (64)
#define EFX_LICENSE_V3_KEY_LENGTH_MAX (128)
#define EFX_LICENSE_V3_HASH_LENGTH (64)
)
{
}
)
{
}
)
{
}
)
{
// Check key is a valid V3 key
if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
goto fail1;
}
goto fail2;
}
if (key_type < 3) {
goto fail3;
}
if (key_length != length) {
goto fail4;
}
return (B_TRUE);
return (B_FALSE);
}
)
{
}
)
{
}
)
{
goto fail1;
}
return (0);
return (rc);
}
)
{
// Construct empty partition
bufferp, buffer_size)) != 0) {
goto fail1;
}
return (0);
return (rc);
}
)
{
buffer_size)) != 0) {
goto fail1;
}
// Validate completed partition
bufferp, buffer_size)) != 0) {
goto fail2;
}
return (0);
return (rc);
}
#endif /* EFSYS_OPT_MEDFORD */
{
const efx_lic_ops_t *elop;
#if EFSYS_OPT_SIENA
case EFX_FAMILY_SIENA:
elop = &__efx_lic_v1_ops;
break;
#endif /* EFSYS_OPT_SIENA */
case EFX_FAMILY_HUNTINGTON:
elop = &__efx_lic_v2_ops;
break;
#endif /* EFSYS_OPT_HUNTINGTON */
case EFX_FAMILY_MEDFORD:
elop = &__efx_lic_v3_ops;
break;
#endif /* EFSYS_OPT_MEDFORD */
default:
EFSYS_ASSERT(0);
goto fail1;
}
return (0);
return (rc);
}
void
{
}
{
goto fail1;
return (0);
return (rc);
}
{
goto fail1;
return (0);
return (rc);
}
{
goto fail1;
}
goto fail2;
return (0);
return (rc);
}
)
{
goto fail1;
}
goto fail2;
return (0);
return (rc);
}
/* Buffer management API - abstracts varying TLV format used for License partition */
)
{
goto fail1;
return (0);
return (rc);
}
)
{
goto fail1;
return (0);
return (rc);
}
)
{
}
/* Validate that the buffer contains a single key in a recognised format.
** An empty or terminator buffer is not accepted as a valid key.
*/
)
{
goto fail1;
return (B_TRUE);
return (rc);
}
)
{
goto fail1;
return (0);
return (rc);
}
)
{
goto fail1;
return (0);
return (rc);
}
)
{
goto fail1;
return (0);
return (rc);
}
)
{
goto fail1;
return (0);
return (rc);
}
)
{
goto fail1;
return (0);
return (rc);
}
#endif /* EFSYS_OPT_LICENSING */