get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/35257/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 35257,
    "url": "http://patches.dpdk.org/api/patches/35257/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1519112078-20113-80-git-send-email-arybchenko@solarflare.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1519112078-20113-80-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1519112078-20113-80-git-send-email-arybchenko@solarflare.com",
    "date": "2018-02-20T07:34:37",
    "name": "[dpdk-dev,79/80] net/sfc/base: add signed image layout support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "a2497ffca2df31e9958a276af887c8eb09e38c44",
    "submitter": {
        "id": 607,
        "url": "http://patches.dpdk.org/api/people/607/?format=api",
        "name": "Andrew Rybchenko",
        "email": "arybchenko@solarflare.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1519112078-20113-80-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/35257/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/35257/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id E678B1B346;\n\tTue, 20 Feb 2018 08:35:51 +0100 (CET)",
            "from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com\n\t[67.231.154.164]) by dpdk.org (Postfix) with ESMTP id 955C61B1C9\n\tfor <dev@dpdk.org>; Tue, 20 Feb 2018 08:35:24 +0100 (CET)",
            "from webmail.solarflare.com (webmail.solarflare.com\n\t[12.187.104.26])\n\t(using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1-us3.ppe-hosted.com (Proofpoint Essentials ESMTP Server) with\n\tESMTPS id\n\t66DA96C0053 for <dev@dpdk.org>; Tue, 20 Feb 2018 07:35:23 +0000 (UTC)",
            "from ocex03.SolarFlarecom.com (10.20.40.36) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id 15.0.1044.25; Mon, 19 Feb 2018 23:35:17 -0800",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id\n\t15.0.1044.25 via Frontend Transport; Mon, 19 Feb 2018 23:35:16 -0800",
            "from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com\n\t[10.17.10.10])\n\tby opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tw1K7ZFQ2025308; Tue, 20 Feb 2018 07:35:15 GMT",
            "from uklogin.uk.solarflarecom.com (localhost.localdomain\n\t[127.0.0.1])\n\tby uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tw1K7ZBuV020529; Tue, 20 Feb 2018 07:35:15 GMT"
        ],
        "X-Virus-Scanned": "Proofpoint Essentials engine",
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Andy Moreton <amoreton@solarflare.com>",
        "Date": "Tue, 20 Feb 2018 07:34:37 +0000",
        "Message-ID": "<1519112078-20113-80-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.2.3",
        "In-Reply-To": "<1519112078-20113-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1519112078-20113-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-MDID": "1519112124-tCUbuDs5SU5O",
        "Subject": "[dpdk-dev] [PATCH 79/80] net/sfc/base: add signed image layout\n\tsupport",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Andy Moreton <amoreton@solarflare.com>\n\nSigned-off-by: Andy Moreton <amoreton@solarflare.com>\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\n---\n drivers/net/sfc/base/ef10_image.c | 867 +++++++++++++++++++++++++++++++++++++-\n drivers/net/sfc/base/efx.h        |  86 ++++\n 2 files changed, 952 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/sfc/base/ef10_image.c b/drivers/net/sfc/base/ef10_image.c\nindex e076f40..6fb7e47 100644\n--- a/drivers/net/sfc/base/ef10_image.c\n+++ b/drivers/net/sfc/base/ef10_image.c\n@@ -11,7 +11,872 @@\n \n #if EFSYS_OPT_IMAGE_LAYOUT\n \n-#include \"ef10_signed_image_layout.h\"\n+/*\n+ * Utility routines to support limited parsing of ASN.1 tags. This is not a\n+ * general purpose ASN.1 parser, but is sufficient to locate the required\n+ * objects in a signed image with CMS headers.\n+ */\n+\n+/* DER encodings for ASN.1 tags (see ITU-T X.690) */\n+#define\tASN1_TAG_INTEGER\t    (0x02)\n+#define\tASN1_TAG_OCTET_STRING\t    (0x04)\n+#define\tASN1_TAG_OBJ_ID\t\t    (0x06)\n+#define\tASN1_TAG_SEQUENCE\t    (0x30)\n+#define\tASN1_TAG_SET\t\t    (0x31)\n+\n+#define\tASN1_TAG_IS_PRIM(tag)\t    ((tag & 0x20) == 0)\n+\n+#define\tASN1_TAG_PRIM_CONTEXT(n)    (0x80 + (n))\n+#define\tASN1_TAG_CONS_CONTEXT(n)    (0xA0 + (n))\n+\n+typedef struct efx_asn1_cursor_s {\n+\tuint8_t\t\t*buffer;\n+\tuint32_t\tlength;\n+\n+\tuint8_t\t\ttag;\n+\tuint32_t\thdr_size;\n+\tuint32_t\tval_size;\n+} efx_asn1_cursor_t;\n+\n+\n+/* Parse header of DER encoded ASN.1 TLV and match tag */\n+static\t__checkReturn\tefx_rc_t\n+efx_asn1_parse_header_match_tag(\n+\t__inout\t\tefx_asn1_cursor_t\t*cursor,\n+\t__in\t\tuint8_t\t\t\ttag)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (cursor == NULL || cursor->buffer == NULL || cursor->length < 2) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tcursor->tag = cursor->buffer[0];\n+\tif (cursor->tag != tag) {\n+\t\t/* Tag not matched */\n+\t\trc = ENOENT;\n+\t\tgoto fail2;\n+\t}\n+\n+\tif ((cursor->tag & 0x1F) == 0x1F) {\n+\t\t/* Long tag format not used in CMS syntax */\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+\n+\tif ((cursor->buffer[1] & 0x80) == 0) {\n+\t\t/* Short form: length is 0..127 */\n+\t\tcursor->hdr_size = 2;\n+\t\tcursor->val_size = cursor->buffer[1];\n+\t} else {\n+\t\t/* Long form: length encoded as [0x80+nbytes][length bytes] */\n+\t\tuint32_t nbytes = cursor->buffer[1] & 0x7F;\n+\t\tuint32_t offset;\n+\n+\t\tif (nbytes == 0) {\n+\t\t\t/* Indefinite length not allowed in DER encoding */\n+\t\t\trc = EINVAL;\n+\t\t\tgoto fail4;\n+\t\t}\n+\t\tif (2 + nbytes > cursor->length) {\n+\t\t\t/* Header length overflows image buffer */\n+\t\t\trc = EINVAL;\n+\t\t\tgoto fail6;\n+\t\t}\n+\t\tif (nbytes > sizeof (uint32_t)) {\n+\t\t\t/* Length encoding too big */\n+\t\t\trc = E2BIG;\n+\t\t\tgoto fail5;\n+\t\t}\n+\t\tcursor->hdr_size = 2 + nbytes;\n+\t\tcursor->val_size = 0;\n+\t\tfor (offset = 2; offset < cursor->hdr_size; offset++) {\n+\t\t\tcursor->val_size =\n+\t\t\t    (cursor->val_size << 8) | cursor->buffer[offset];\n+\t\t}\n+\t}\n+\n+\tif ((cursor->hdr_size + cursor->val_size) > cursor->length) {\n+\t\t/* Length overflows image buffer */\n+\t\trc = E2BIG;\n+\t\tgoto fail7;\n+\t}\n+\n+\treturn (0);\n+\n+fail7:\n+\tEFSYS_PROBE(fail7);\n+fail6:\n+\tEFSYS_PROBE(fail6);\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+/* Enter nested ASN.1 TLV (contained in value of current TLV) */\n+static\t__checkReturn\tefx_rc_t\n+efx_asn1_enter_tag(\n+\t__inout\t\tefx_asn1_cursor_t\t*cursor,\n+\t__in\t\tuint8_t\t\t\ttag)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (cursor == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\tif (ASN1_TAG_IS_PRIM(tag)) {\n+\t\t/* Cannot enter a primitive tag */\n+\t\trc = ENOTSUP;\n+\t\tgoto fail2;\n+\t}\n+\trc = efx_asn1_parse_header_match_tag(cursor, tag);\n+\tif (rc != 0) {\n+\t\t/* Invalid TLV or wrong tag */\n+\t\tgoto fail3;\n+\t}\n+\n+\t/* Limit cursor range to nested TLV */\n+\tcursor->buffer += cursor->hdr_size;\n+\tcursor->length = cursor->val_size;\n+\n+\treturn (0);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+/*\n+ * Check that the current ASN.1 TLV matches the given tag and value.\n+ * Advance cursor to next TLV on a successful match.\n+ */\n+static\t__checkReturn\tefx_rc_t\n+efx_asn1_match_tag_value(\n+\t__inout\t\tefx_asn1_cursor_t\t*cursor,\n+\t__in\t\tuint8_t\t\t\ttag,\n+\t__in\t\tconst void\t\t*valp,\n+\t__in\t\tuint32_t\t\tval_size)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (cursor == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\trc = efx_asn1_parse_header_match_tag(cursor, tag);\n+\tif (rc != 0) {\n+\t\t/* Invalid TLV or wrong tag */\n+\t\tgoto fail2;\n+\t}\n+\tif (cursor->val_size != val_size) {\n+\t\t/* Value size is different */\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+\tif (memcmp(cursor->buffer + cursor->hdr_size, valp, val_size) != 0) {\n+\t\t/* Value content is different */\n+\t\trc = EINVAL;\n+\t\tgoto fail4;\n+\t}\n+\tcursor->buffer += cursor->hdr_size + cursor->val_size;\n+\tcursor->length -= cursor->hdr_size + cursor->val_size;\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+/* Advance cursor to next TLV */\n+static\t__checkReturn\tefx_rc_t\n+efx_asn1_skip_tag(\n+\t__inout\t\tefx_asn1_cursor_t\t*cursor,\n+\t__in\t\tuint8_t\t\t\ttag)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (cursor == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\trc = efx_asn1_parse_header_match_tag(cursor, tag);\n+\tif (rc != 0) {\n+\t\t/* Invalid TLV or wrong tag */\n+\t\tgoto fail2;\n+\t}\n+\tcursor->buffer += cursor->hdr_size + cursor->val_size;\n+\tcursor->length -= cursor->hdr_size + cursor->val_size;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+/* Return pointer to value octets and value size from current TLV */\n+static\t__checkReturn\tefx_rc_t\n+efx_asn1_get_tag_value(\n+\t__inout\t\tefx_asn1_cursor_t\t*cursor,\n+\t__in\t\tuint8_t\t\t\ttag,\n+\t__out\t\tuint8_t\t\t\t**valp,\n+\t__out\t\tuint32_t\t\t*val_sizep)\n+{\n+\tefx_rc_t rc;\n+\n+\tif (cursor == NULL || valp == NULL || val_sizep == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\n+\trc = efx_asn1_parse_header_match_tag(cursor, tag);\n+\tif (rc != 0) {\n+\t\t/* Invalid TLV or wrong tag */\n+\t\tgoto fail2;\n+\t}\n+\t*valp = cursor->buffer + cursor->hdr_size;\n+\t*val_sizep = cursor->val_size;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\n+/*\n+ * Utility routines for parsing CMS headers (see RFC2315, PKCS#7)\n+ */\n+\n+/* OID 1.2.840.113549.1.7.2 */\n+static const uint8_t PKCS7_SignedData[] =\n+{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };\n+\n+/* OID 1.2.840.113549.1.7.1 */\n+static const uint8_t PKCS7_Data[] =\n+{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };\n+\n+/* SignedData structure version */\n+static const uint8_t SignedData_Version[] =\n+{ 0x03 };\n+\n+/*\n+ * Check for a valid image in signed image format. This uses CMS syntax\n+ * (see RFC2315, PKCS#7) to provide signatures, and certificates required\n+ * to validate the signatures. The encapsulated content is in unsigned image\n+ * format (reflash header, image code, trailer checksum).\n+ */\n+static\t__checkReturn\tefx_rc_t\n+efx_check_signed_image_header(\n+\t__in\t\tvoid\t\t*bufferp,\n+\t__in\t\tuint32_t\tbuffer_size,\n+\t__out\t\tuint32_t\t*content_offsetp,\n+\t__out\t\tuint32_t\t*content_lengthp)\n+{\n+\tefx_asn1_cursor_t cursor;\n+\tuint8_t *valp;\n+\tuint32_t val_size;\n+\tefx_rc_t rc;\n+\n+\tif (content_offsetp == NULL || content_lengthp == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\tcursor.buffer = (uint8_t *)bufferp;\n+\tcursor.length = buffer_size;\n+\n+\t/* ContextInfo */\n+\trc = efx_asn1_enter_tag(&cursor, ASN1_TAG_SEQUENCE);\n+\tif (rc != 0)\n+\t\tgoto fail2;\n+\n+\t/* ContextInfo.contentType */\n+\trc = efx_asn1_match_tag_value(&cursor, ASN1_TAG_OBJ_ID,\n+\t    PKCS7_SignedData, sizeof (PKCS7_SignedData));\n+\tif (rc != 0)\n+\t\tgoto fail3;\n+\n+\t/* ContextInfo.content */\n+\trc = efx_asn1_enter_tag(&cursor, ASN1_TAG_CONS_CONTEXT(0));\n+\tif (rc != 0)\n+\t\tgoto fail4;\n+\n+\t/* SignedData */\n+\trc = efx_asn1_enter_tag(&cursor, ASN1_TAG_SEQUENCE);\n+\tif (rc != 0)\n+\t\tgoto fail5;\n+\n+\t/* SignedData.version */\n+\trc = efx_asn1_match_tag_value(&cursor, ASN1_TAG_INTEGER,\n+\t    SignedData_Version, sizeof (SignedData_Version));\n+\tif (rc != 0)\n+\t\tgoto fail6;\n+\n+\t/* SignedData.digestAlgorithms */\n+\trc = efx_asn1_skip_tag(&cursor, ASN1_TAG_SET);\n+\tif (rc != 0)\n+\t\tgoto fail7;\n+\n+\t/* SignedData.encapContentInfo */\n+\trc = efx_asn1_enter_tag(&cursor, ASN1_TAG_SEQUENCE);\n+\tif (rc != 0)\n+\t\tgoto fail8;\n+\n+\t/* SignedData.encapContentInfo.econtentType */\n+\trc = efx_asn1_match_tag_value(&cursor, ASN1_TAG_OBJ_ID,\n+\t    PKCS7_Data, sizeof (PKCS7_Data));\n+\tif (rc != 0)\n+\t\tgoto fail9;\n+\n+\t/* SignedData.encapContentInfo.econtent */\n+\trc = efx_asn1_enter_tag(&cursor, ASN1_TAG_CONS_CONTEXT(0));\n+\tif (rc != 0)\n+\t\tgoto fail10;\n+\n+\t/*\n+\t * The octet string contains the image header, image code bytes and\n+\t * image trailer CRC (same as unsigned image layout).\n+\t */\n+\tvalp = NULL;\n+\tval_size = 0;\n+\trc = efx_asn1_get_tag_value(&cursor, ASN1_TAG_OCTET_STRING,\n+\t    &valp, &val_size);\n+\tif (rc != 0)\n+\t\tgoto fail11;\n+\n+\tif ((valp == NULL) || (val_size == 0)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail12;\n+\t}\n+\tif (valp < (uint8_t *)bufferp) {\n+\t\trc = EINVAL;\n+\t\tgoto fail13;\n+\t}\n+\tif ((valp + val_size) > ((uint8_t *)bufferp + buffer_size)) {\n+\t\trc = EINVAL;\n+\t\tgoto fail14;\n+\t}\n+\n+\t*content_offsetp = (uint32_t)(valp - (uint8_t *)bufferp);\n+\t*content_lengthp = val_size;\n+\n+\treturn (0);\n+\n+fail14:\n+\tEFSYS_PROBE(fail14);\n+fail13:\n+\tEFSYS_PROBE(fail13);\n+fail12:\n+\tEFSYS_PROBE(fail12);\n+fail11:\n+\tEFSYS_PROBE(fail11);\n+fail10:\n+\tEFSYS_PROBE(fail10);\n+fail9:\n+\tEFSYS_PROBE(fail9);\n+fail8:\n+\tEFSYS_PROBE(fail8);\n+fail7:\n+\tEFSYS_PROBE(fail7);\n+fail6:\n+\tEFSYS_PROBE(fail6);\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+efx_check_unsigned_image(\n+\t__in\t\tvoid\t\t*bufferp,\n+\t__in\t\tuint32_t\tbuffer_size)\n+{\n+\tefx_image_header_t *header;\n+\tefx_image_trailer_t *trailer;\n+\tuint32_t crc;\n+\tefx_rc_t rc;\n+\n+\tEFX_STATIC_ASSERT(sizeof (*header) == EFX_IMAGE_HEADER_SIZE);\n+\tEFX_STATIC_ASSERT(sizeof (*trailer) == EFX_IMAGE_TRAILER_SIZE);\n+\n+\t/* Must have at least enough space for required image header fields */\n+\tif (buffer_size < (EFX_FIELD_OFFSET(efx_image_header_t, eih_size) +\n+\t\tsizeof (header->eih_size))) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail1;\n+\t}\n+\theader = (efx_image_header_t *)bufferp;\n+\n+\tif (header->eih_magic != EFX_IMAGE_HEADER_MAGIC) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\t/*\n+\t * Check image header version is same or higher than lowest required\n+\t * version.\n+\t */\n+\tif (header->eih_version < EFX_IMAGE_HEADER_VERSION) {\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+\n+\t/* Buffer must have space for image header, code and image trailer. */\n+\tif (buffer_size < (header->eih_size + header->eih_code_size +\n+\t\tEFX_IMAGE_TRAILER_SIZE)) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail4;\n+\t}\n+\n+\t/* Check CRC from image buffer matches computed CRC. */\n+\ttrailer = (efx_image_trailer_t *)((uint8_t *)header +\n+\t    header->eih_size + header->eih_code_size);\n+\n+\tcrc = efx_crc32_calculate(0, (uint8_t *)header,\n+\t    (header->eih_size + header->eih_code_size));\n+\n+\tif (trailer->eit_crc != crc) {\n+\t\trc = EINVAL;\n+\t\tgoto fail5;\n+\t}\n+\n+\treturn (0);\n+\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+efx_check_reflash_image(\n+\t__in\t\tvoid\t\t\t*bufferp,\n+\t__in\t\tuint32_t\t\tbuffer_size,\n+\t__out\t\tefx_image_info_t\t*infop)\n+{\n+\tefx_image_format_t format = EFX_IMAGE_FORMAT_NO_IMAGE;\n+\tuint32_t image_offset;\n+\tuint32_t image_size;\n+\tvoid *imagep;\n+\tefx_rc_t rc;\n+\n+\n+\tEFSYS_ASSERT(infop != NULL);\n+\tif (infop == NULL) {\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\tmemset(infop, 0, sizeof (*infop));\n+\n+\tif (bufferp == NULL || buffer_size == 0) {\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\t/*\n+\t * Check if the buffer contains an image in signed format, and if so,\n+\t * locate the image header.\n+\t */\n+\trc = efx_check_signed_image_header(bufferp, buffer_size,\n+\t    &image_offset, &image_size);\n+\tif (rc == 0) {\n+\t\t/*\n+\t\t * Buffer holds signed image format. Check that the encapsulated\n+\t\t * content is in unsigned image format.\n+\t\t */\n+\t\tformat = EFX_IMAGE_FORMAT_SIGNED;\n+\t} else {\n+\t\t/* Check if the buffer holds image in unsigned image format */\n+\t\tformat = EFX_IMAGE_FORMAT_UNSIGNED;\n+\t\timage_offset = 0;\n+\t\timage_size = buffer_size;\n+\t}\n+\tif (image_offset + image_size > buffer_size) {\n+\t\trc = E2BIG;\n+\t\tgoto fail3;\n+\t}\n+\timagep = (uint8_t *)bufferp + image_offset;\n+\n+\t/* Check unsigned image layout (image header, code, image trailer) */\n+\trc = efx_check_unsigned_image(imagep, image_size);\n+\tif (rc != 0)\n+\t\tgoto fail4;\n+\n+\t/* Return image details */\n+\tinfop->eii_format = format;\n+\tinfop->eii_imagep = bufferp;\n+\tinfop->eii_image_size = buffer_size;\n+\tinfop->eii_headerp = (efx_image_header_t *)imagep;\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+\tinfop->eii_format = EFX_IMAGE_FORMAT_INVALID;\n+\tinfop->eii_imagep = NULL;\n+\tinfop->eii_image_size = 0;\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\tefx_rc_t\n+efx_build_signed_image_write_buffer(\n+\t__out\t\tuint8_t\t\t\t*bufferp,\n+\t__in\t\tuint32_t\t\tbuffer_size,\n+\t__in\t\tefx_image_info_t\t*infop,\n+\t__out\t\tefx_image_header_t\t**headerpp)\n+{\n+\tsigned_image_chunk_hdr_t chunk_hdr;\n+\tuint32_t hdr_offset;\n+\tstruct {\n+\t\tuint32_t offset;\n+\t\tuint32_t size;\n+\t} cms_header, image_header, code, image_trailer, signature;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT((infop != NULL) && (headerpp != NULL));\n+\n+\tif ((bufferp == NULL) || (buffer_size == 0) ||\n+\t    (infop == NULL) || (headerpp == NULL)) {\n+\t\t/* Invalid arguments */\n+\t\trc = EINVAL;\n+\t\tgoto fail1;\n+\t}\n+\tif ((infop->eii_format != EFX_IMAGE_FORMAT_SIGNED) ||\n+\t    (infop->eii_imagep == NULL) ||\n+\t    (infop->eii_headerp == NULL) ||\n+\t    ((uint8_t *)infop->eii_headerp < (uint8_t *)infop->eii_imagep) ||\n+\t    (infop->eii_image_size < EFX_IMAGE_HEADER_SIZE) ||\n+\t    ((size_t)((uint8_t *)infop->eii_headerp - infop->eii_imagep) >\n+\t    (infop->eii_image_size - EFX_IMAGE_HEADER_SIZE))) {\n+\t\t/* Invalid image info */\n+\t\trc = EINVAL;\n+\t\tgoto fail2;\n+\t}\n+\n+\t/* Locate image chunks in original signed image */\n+\tcms_header.offset = 0;\n+\tcms_header.size =\n+\t    (uint32_t)((uint8_t *)infop->eii_headerp - infop->eii_imagep);\n+\tif ((cms_header.size > buffer_size) ||\n+\t    (cms_header.offset > (buffer_size - cms_header.size))) {\n+\t\trc = EINVAL;\n+\t\tgoto fail3;\n+\t}\n+\n+\timage_header.offset = cms_header.offset + cms_header.size;\n+\timage_header.size = infop->eii_headerp->eih_size;\n+\tif ((image_header.size > buffer_size) ||\n+\t    (image_header.offset > (buffer_size - image_header.size))) {\n+\t\trc = EINVAL;\n+\t\tgoto fail4;\n+\t}\n+\n+\tcode.offset = image_header.offset + image_header.size;\n+\tcode.size = infop->eii_headerp->eih_code_size;\n+\tif ((code.size > buffer_size) ||\n+\t    (code.offset > (buffer_size - code.size))) {\n+\t\trc = EINVAL;\n+\t\tgoto fail5;\n+\t}\n+\n+\timage_trailer.offset = code.offset + code.size;\n+\timage_trailer.size = EFX_IMAGE_TRAILER_SIZE;\n+\tif ((image_trailer.size > buffer_size) ||\n+\t    (image_trailer.offset > (buffer_size - image_trailer.size))) {\n+\t\trc = EINVAL;\n+\t\tgoto fail6;\n+\t}\n+\n+\tsignature.offset = image_trailer.offset + image_trailer.size;\n+\tsignature.size = (uint32_t)(infop->eii_image_size - signature.offset);\n+\tif ((signature.size > buffer_size) ||\n+\t    (signature.offset > (buffer_size - signature.size))) {\n+\t\trc = EINVAL;\n+\t\tgoto fail7;\n+\t}\n+\n+\tEFSYS_ASSERT3U(infop->eii_image_size, ==, cms_header.size +\n+\t    image_header.size + code.size + image_trailer.size +\n+\t    signature.size);\n+\n+\t/* BEGIN CSTYLED */\n+\t/*\n+\t * Build signed image partition, inserting chunk headers.\n+\t *\n+\t *  Signed Image:                  Image in NVRAM partition:\n+\t *\n+\t *  +-----------------+            +-----------------+\n+\t *  | CMS header      |            |  mcfw.update    |<----+\n+\t *  +-----------------+            |                 |     |\n+\t *  | reflash header  |            +-----------------+     |\n+\t *  +-----------------+            | chunk header:   |-->--|-+\n+\t *  | mcfw.update     |            | REFLASH_TRAILER |     | |\n+\t *  |                 |            +-----------------+     | |\n+\t *  +-----------------+        +-->| CMS header      |     | |\n+\t *  | reflash trailer |        |   +-----------------+     | |\n+\t *  +-----------------+        |   | chunk header:   |->-+ | |\n+\t *  | signature       |        |   | REFLASH_HEADER  |   | | |\n+\t *  +-----------------+        |   +-----------------+   | | |\n+\t *                             |   | reflash header  |<--+ | |\n+\t *                             |   +-----------------+     | |\n+\t *                             |   | chunk header:   |-->--+ |\n+\t *                             |   | IMAGE           |       |\n+\t *                             |   +-----------------+       |\n+\t *                             |   | reflash trailer |<------+\n+\t *                             |   +-----------------+\n+\t *                             |   | chunk header:   |\n+\t *                             |   | SIGNATURE       |->-+\n+\t *                             |   +-----------------+   |\n+\t *                             |   | signature       |<--+\n+\t *                             |   +-----------------+\n+\t *                             |   | ...unused...    |\n+\t *                             |   +-----------------+\n+\t *                             +-<-| chunk header:   |\n+\t *                             >-->| CMS_HEADER      |\n+\t *                                 +-----------------+\n+\t *\n+\t * Each chunk header gives the partition offset and length of the image\n+\t * chunk's data. The image chunk data is immediately followed by the\n+\t * chunk header for the next chunk.\n+\t *\n+\t * The data chunk for the firmware code must be at the start of the\n+\t * partition (needed for the bootloader). The first chunk header in the\n+\t * chain (for the CMS header) is stored at the end of the partition. The\n+\t * chain of chunk headers maintains the same logical order of image\n+\t * chunks as the original signed image file. This set of constraints\n+\t * results in the layout used for the data chunks and chunk headers.\n+\t */\n+\t/* END CSTYLED */\n+\tmemset(bufferp, buffer_size, 0xFF);\n+\n+\tEFX_STATIC_ASSERT(sizeof (chunk_hdr) == SIGNED_IMAGE_CHUNK_HDR_LEN);\n+\tmemset(&chunk_hdr, 0, SIGNED_IMAGE_CHUNK_HDR_LEN);\n+\n+\t/*\n+\t * CMS header\n+\t */\n+\tif (buffer_size < SIGNED_IMAGE_CHUNK_HDR_LEN) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail8;\n+\t}\n+\thdr_offset = buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN;\n+\n+\tchunk_hdr.magic\t\t= SIGNED_IMAGE_CHUNK_HDR_MAGIC;\n+\tchunk_hdr.version\t= SIGNED_IMAGE_CHUNK_HDR_VERSION;\n+\tchunk_hdr.id\t\t= SIGNED_IMAGE_CHUNK_CMS_HEADER;\n+\tchunk_hdr.offset\t= code.size + SIGNED_IMAGE_CHUNK_HDR_LEN;\n+\tchunk_hdr.len\t\t= cms_header.size;\n+\n+\tmemcpy(bufferp + hdr_offset, &chunk_hdr, sizeof (chunk_hdr));\n+\n+\tif ((chunk_hdr.len > buffer_size) ||\n+\t    (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail9;\n+\t}\n+\tmemcpy(bufferp + chunk_hdr.offset,\n+\t    infop->eii_imagep + cms_header.offset,\n+\t    cms_header.size);\n+\n+\t/*\n+\t * Image header\n+\t */\n+\thdr_offset = chunk_hdr.offset + chunk_hdr.len;\n+\tif (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail10;\n+\t}\n+\tchunk_hdr.magic\t\t= SIGNED_IMAGE_CHUNK_HDR_MAGIC;\n+\tchunk_hdr.version\t= SIGNED_IMAGE_CHUNK_HDR_VERSION;\n+\tchunk_hdr.id\t\t= SIGNED_IMAGE_CHUNK_REFLASH_HEADER;\n+\tchunk_hdr.offset\t= hdr_offset + SIGNED_IMAGE_CHUNK_HDR_LEN;\n+\tchunk_hdr.len\t\t= image_header.size;\n+\n+\tmemcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);\n+\n+\tif ((chunk_hdr.len > buffer_size) ||\n+\t    (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail11;\n+\t}\n+\tmemcpy(bufferp + chunk_hdr.offset,\n+\t    infop->eii_imagep + image_header.offset,\n+\t    image_header.size);\n+\n+\t*headerpp = (efx_image_header_t *)(bufferp + chunk_hdr.offset);\n+\n+\t/*\n+\t * Firmware code\n+\t */\n+\thdr_offset = chunk_hdr.offset + chunk_hdr.len;\n+\tif (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail12;\n+\t}\n+\tchunk_hdr.magic\t\t= SIGNED_IMAGE_CHUNK_HDR_MAGIC;\n+\tchunk_hdr.version\t= SIGNED_IMAGE_CHUNK_HDR_VERSION;\n+\tchunk_hdr.id\t\t= SIGNED_IMAGE_CHUNK_IMAGE;\n+\tchunk_hdr.offset\t= 0;\n+\tchunk_hdr.len\t\t= code.size;\n+\n+\tmemcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);\n+\n+\tif ((chunk_hdr.len > buffer_size) ||\n+\t    (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail13;\n+\t}\n+\tmemcpy(bufferp + chunk_hdr.offset,\n+\t    infop->eii_imagep + code.offset,\n+\t    code.size);\n+\n+\t/*\n+\t * Image trailer (CRC)\n+\t */\n+\tchunk_hdr.magic\t\t= SIGNED_IMAGE_CHUNK_HDR_MAGIC;\n+\tchunk_hdr.version\t= SIGNED_IMAGE_CHUNK_HDR_VERSION;\n+\tchunk_hdr.id\t\t= SIGNED_IMAGE_CHUNK_REFLASH_TRAILER;\n+\tchunk_hdr.offset\t= hdr_offset + SIGNED_IMAGE_CHUNK_HDR_LEN;\n+\tchunk_hdr.len\t\t= image_trailer.size;\n+\n+\thdr_offset = code.size;\n+\tif (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail14;\n+\t}\n+\n+\tmemcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);\n+\n+\tif ((chunk_hdr.len > buffer_size) ||\n+\t    (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail15;\n+\t}\n+\tmemcpy((uint8_t *)bufferp + chunk_hdr.offset,\n+\t    infop->eii_imagep + image_trailer.offset,\n+\t    image_trailer.size);\n+\n+\t/*\n+\t * Signature\n+\t */\n+\thdr_offset = chunk_hdr.offset + chunk_hdr.len;\n+\tif (hdr_offset > (buffer_size - SIGNED_IMAGE_CHUNK_HDR_LEN)) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail16;\n+\t}\n+\tchunk_hdr.magic\t\t= SIGNED_IMAGE_CHUNK_HDR_MAGIC;\n+\tchunk_hdr.version\t= SIGNED_IMAGE_CHUNK_HDR_VERSION;\n+\tchunk_hdr.id\t\t= SIGNED_IMAGE_CHUNK_SIGNATURE;\n+\tchunk_hdr.offset\t= chunk_hdr.offset + SIGNED_IMAGE_CHUNK_HDR_LEN;\n+\tchunk_hdr.len\t\t= signature.size;\n+\n+\tmemcpy(bufferp + hdr_offset, &chunk_hdr, SIGNED_IMAGE_CHUNK_HDR_LEN);\n+\n+\tif ((chunk_hdr.len > buffer_size) ||\n+\t    (chunk_hdr.offset > (buffer_size - chunk_hdr.len))) {\n+\t\trc = ENOSPC;\n+\t\tgoto fail17;\n+\t}\n+\tmemcpy(bufferp + chunk_hdr.offset,\n+\t    infop->eii_imagep + signature.offset,\n+\t    signature.size);\n+\n+\treturn (0);\n+\n+fail17:\n+\tEFSYS_PROBE(fail17);\n+fail16:\n+\tEFSYS_PROBE(fail16);\n+fail15:\n+\tEFSYS_PROBE(fail15);\n+fail14:\n+\tEFSYS_PROBE(fail14);\n+fail13:\n+\tEFSYS_PROBE(fail13);\n+fail12:\n+\tEFSYS_PROBE(fail12);\n+fail11:\n+\tEFSYS_PROBE(fail11);\n+fail10:\n+\tEFSYS_PROBE(fail10);\n+fail9:\n+\tEFSYS_PROBE(fail9);\n+fail8:\n+\tEFSYS_PROBE(fail8);\n+fail7:\n+\tEFSYS_PROBE(fail7);\n+fail6:\n+\tEFSYS_PROBE(fail6);\n+fail5:\n+\tEFSYS_PROBE(fail5);\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n \n \n \ndiff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h\nindex 0d84108..088a896 100644\n--- a/drivers/net/sfc/base/efx.h\n+++ b/drivers/net/sfc/base/efx.h\n@@ -1567,6 +1567,92 @@ efx_bootcfg_write(\n \n #endif\t/* EFSYS_OPT_BOOTCFG */\n \n+#if EFSYS_OPT_IMAGE_LAYOUT\n+\n+#include \"ef10_signed_image_layout.h\"\n+\n+/*\n+ * Image header used in unsigned and signed image layouts (see SF-102785-PS).\n+ *\n+ * NOTE:\n+ * The image header format is extensible. However, older drivers require an\n+ * exact match of image header version and header length when validating and\n+ * writing firmware images.\n+ *\n+ * To avoid breaking backward compatibility, we use the upper bits of the\n+ * controller version fields to contain an extra version number used for\n+ * combined bootROM and UEFI ROM images on EF10 and later (to hold the UEFI ROM\n+ * version). See bug39254 and SF-102785-PS for details.\n+ */\n+typedef struct efx_image_header_s {\n+\tuint32_t\teih_magic;\n+\tuint32_t\teih_version;\n+\tuint32_t\teih_type;\n+\tuint32_t\teih_subtype;\n+\tuint32_t\teih_code_size;\n+\tuint32_t\teih_size;\n+\tunion {\n+\t\tuint32_t\teih_controller_version_min;\n+\t\tstruct {\n+\t\t\tuint16_t\teih_controller_version_min_short;\n+\t\t\tuint8_t\t\teih_extra_version_a;\n+\t\t\tuint8_t\t\teih_extra_version_b;\n+\t\t};\n+\t};\n+\tunion {\n+\t\tuint32_t\teih_controller_version_max;\n+\t\tstruct {\n+\t\t\tuint16_t\teih_controller_version_max_short;\n+\t\t\tuint8_t\t\teih_extra_version_c;\n+\t\t\tuint8_t\t\teih_extra_version_d;\n+\t\t};\n+\t};\n+\tuint16_t\teih_code_version_a;\n+\tuint16_t\teih_code_version_b;\n+\tuint16_t\teih_code_version_c;\n+\tuint16_t\teih_code_version_d;\n+} efx_image_header_t;\n+\n+#define\tEFX_IMAGE_HEADER_SIZE\t\t(40)\n+#define\tEFX_IMAGE_HEADER_VERSION\t(4)\n+#define\tEFX_IMAGE_HEADER_MAGIC\t\t(0x106F1A5)\n+\n+\n+typedef struct efx_image_trailer_s {\n+\tuint32_t\teit_crc;\n+} efx_image_trailer_t;\n+\n+#define\tEFX_IMAGE_TRAILER_SIZE\t\t(4)\n+\n+typedef enum efx_image_format_e {\n+\tEFX_IMAGE_FORMAT_NO_IMAGE,\n+\tEFX_IMAGE_FORMAT_INVALID,\n+\tEFX_IMAGE_FORMAT_UNSIGNED,\n+\tEFX_IMAGE_FORMAT_SIGNED,\n+} efx_image_format_t;\n+\n+typedef struct efx_image_info_s {\n+\tefx_image_format_t\teii_format;\n+\tuint8_t *\t\teii_imagep;\n+\tsize_t\t\t\teii_image_size;\n+\tefx_image_header_t *\teii_headerp;\n+} efx_image_info_t;\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_check_reflash_image(\n+\t__in\t\tvoid\t\t\t*bufferp,\n+\t__in\t\tuint32_t\t\tbuffer_size,\n+\t__out\t\tefx_image_info_t\t*infop);\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_build_signed_image_write_buffer(\n+\t__out\t\tuint8_t\t\t\t*bufferp,\n+\t__in\t\tuint32_t\t\tbuffer_size,\n+\t__in\t\tefx_image_info_t\t*infop,\n+\t__out\t\tefx_image_header_t\t**headerpp);\n+\n+#endif\t/* EFSYS_OPT_IMAGE_LAYOUT */\n+\n #if EFSYS_OPT_DIAG\n \n typedef enum efx_pattern_type_t {\n",
    "prefixes": [
        "dpdk-dev",
        "79/80"
    ]
}