From patchwork Thu Jun 21 19:01:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Trimble X-Patchwork-Id: 9471 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:141:0:0:0:0:0 with SMTP id c62-v6csp57670jad; Thu, 21 Jun 2018 12:01:31 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIaC5rFcywPACZzRamWiPOtuG7Tuu10o8mipmptvQkRcg3ZyHjxr84067vnDL4Tsb/dd/MS X-Received: by 2002:a1c:6fce:: with SMTP id c75-v6mr5934316wmi.83.1529607691541; Thu, 21 Jun 2018 12:01:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529607691; cv=none; d=google.com; s=arc-20160816; b=W9C+V+VBlxAqAUFvGBameZYA/DkodyEHMPaSpOOOQ5agxmGSA7f1AD9v88juR0RNaW KOtymXTZ8t5EwhaoVbsAh0L+ucTjDu9XrgQDWKU07agxSJOhpNZihtb9VQyhs5mC0cCY s4v6eyYGX6iSTqHLdQjtKVfvDmvQH3I8xnwIlEdMPhZUYyq2q4Ehx0N4DwlFPgZjInJZ zm0J1M3FCaCO45yDwWIUGs6yIyaNJsn0kDP81ulI1aUTn16vtOPsei0h8mEhAw2BqJ5s iplB2Ga/lJc2UtN2IAUlguLn5VaZ2nAgjMyG9v7uQSBgc/zFFwpHtwX0XStCQ/jkhb80 oelw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:to :message-id:date:from:in-reply-to:references:mime-version :dkim-signature:delivered-to:arc-authentication-results; bh=Cu9xuq/a9ibXb3WsoVRT5471OJYVQBDQ+sv+3UTeIns=; b=A+FeuRlf8rXcOWLhrzQ2k7DkC0SUqKwcnY1dKvX1wGQHd1kRgJRK6xmv+vAw4D7HDt ziRPQQbvuixGoxiWOUDy6SEwv/bpmeM7Ff51+wn1IrB7j25jG1eSR8TrNVa108G7Fo9j 5tXMZUgokZ2mO0HWniplanuL//voDpqFG/QN1NtNO5kUSMKfDAIHaZIci5Y93w1tS7aF nADjUj/jH6FM23lnF2uswl/a8fkS1mvelAr/qErxgdnvEFJ2t6GcajXg+eHZQ0H8eet3 aIDkb1lsmLsECW0JXxuf1I9gIO/ahnO0KaSgrJWmZZL7nKk+A3yAQCSGgMxij5zjBpUe IP7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@google.com header.s=20161025 header.b=j32E7D3L; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 31-v6si982716wra.115.2018.06.21.12.01.30; Thu, 21 Jun 2018 12:01:31 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@google.com header.s=20161025 header.b=j32E7D3L; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F374468A742; Thu, 21 Jun 2018 22:00:34 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf0-f45.google.com (mail-lf0-f45.google.com [209.85.215.45]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D90A768A57C for ; Thu, 21 Jun 2018 22:00:28 +0300 (EEST) Received: by mail-lf0-f45.google.com with SMTP id p23-v6so5821398lfh.11 for ; Thu, 21 Jun 2018 12:01:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=xU7f6Bx3eXzw8EBp5dtivQDGx3SYJdRm5Hlunh8fg9U=; b=j32E7D3LWRJ6mF6Td3HIbbRI4vdhbZ9Ow7cZuc/ga+uEhjf/qAmctslIyWVqFkwXyZ cDjS6i3D1hx1KrMg7fJDLJfVopwnmU4n9E7rlvxT+0QVd7YAsROi20n+Ym0ynE3acsgI n6UyZUwR57SixcopDCpJg+BBcxpqKSjNAa/iowhWRL4bsDgmpOZ5IWMfeGYuYCrXVexM jwTklGNVZqLBmOjH2rqIEHHEpJbtuBwsUWpdyMonDxYz1pUSVCu9/DOnxIRk10lxYB5O 76umE3gQLuU0LePaafMEGkgoZT/Ao1glYq2KHkVrt445vyZ8582l4hiI7RuM3W546m0J IllQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=xU7f6Bx3eXzw8EBp5dtivQDGx3SYJdRm5Hlunh8fg9U=; b=d1QWvbyfexzDHObV5oYzvb5JSswDanFzUjdfA3M40gahYHPhGkc1OWp++MirsQcZdU 2LDTXfoxiW9RI9u6cRDBjliNz+PIgYNiUT/NvbNLz8uhLm/xRJOYCwMiQGz4guamub1k +VNmHZ8L+Atf0UfKavSdIAOWIAad4g6R4LPFhw58p/yE/Ywir/vhTiRFNDf65qY8X3dk R0Ag2aDh2y1+sLfP0rIeiXeJVm8ivjpmjWjor2+O41iaMxJbd9MPMhZebH2nXIUiw6FF mlvK70yn9AAyyKid+NV9cTOeEc8RjQd+Y3QEA/e8+s23Cw/+5Wma91FhTABJi5dwAgd3 1qZQ== X-Gm-Message-State: APt69E13DzgAaUMbQsuzLuCWe/wgJik9ZmMiMp7iMA5A/SUOVgAKsR0h xMKmnBGA7xikP4C015Xw4HkChBMXnbqmNDeV4vNN3jF2 X-Received: by 2002:a19:a586:: with SMTP id o128-v6mr5648981lfe.131.1529607681553; Thu, 21 Jun 2018 12:01:21 -0700 (PDT) MIME-Version: 1.0 References: <20180507221858.GQ20131@michaelspb> <20180508224758.GF20131@michaelspb> <20180526011313.GU4859@michaelspb> <20180621164755.GP4859@michaelspb> In-Reply-To: <20180621164755.GP4859@michaelspb> From: Jacob Trimble Date: Thu, 21 Jun 2018 12:01:09 -0700 Message-ID: To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] libavutil/encryption_info: Allow multiple init info. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" On Thu, Jun 21, 2018 at 9:48 AM Michael Niedermayer wrote: > > > + if (UINT32_MAX == init_info_count || > > + UINT32_MAX - *side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA || > > + UINT32_MAX - *side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < info->system_id_size || > > + UINT32_MAX - *side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA - info->system_id_size < info->data_size) { > > return NULL; > > + } > > you can simplify this with (u)int64_t > Done From f440fe2be172672c439fa8b216b08a8d0895f76f Mon Sep 17 00:00:00 2001 From: Jacob Trimble Date: Mon, 23 Apr 2018 10:33:58 -0700 Subject: [PATCH] libavutil/encryption_info: Allow multiple init info. It is possible for there to be multiple encryption init info structure. For example, to support multiple key systems or in key rotation. This changes the AVEncryptionInitInfo struct to be a linked list so there can be multiple structs without breaking ABI. Signed-off-by: Jacob Trimble --- libavutil/encryption_info.c | 146 +++++++++++++++++++++++------------- libavutil/encryption_info.h | 5 ++ 2 files changed, 100 insertions(+), 51 deletions(-) diff --git a/libavutil/encryption_info.c b/libavutil/encryption_info.c index 20a752d6b4..3b7e16cd0c 100644 --- a/libavutil/encryption_info.c +++ b/libavutil/encryption_info.c @@ -160,13 +160,16 @@ uint8_t *av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t * } // The format of the AVEncryptionInitInfo side data: -// u32be system_id_size -// u32be num_key_ids -// u32be key_id_size -// u32be data_size -// u8[system_id_size] system_id -// u8[key_id_size][num_key_id] key_ids -// u8[data_size] data +// u32be init_info_count +// { +// u32be system_id_size +// u32be num_key_ids +// u32be key_id_size +// u32be data_size +// u8[system_id_size] system_id +// u8[key_id_size][num_key_id] key_ids +// u8[data_size] data +// }[init_info_count] #define FF_ENCRYPTION_INIT_INFO_EXTRA 16 @@ -215,6 +218,7 @@ void av_encryption_init_info_free(AVEncryptionInitInfo *info) for (i = 0; i < info->num_key_ids; i++) { av_free(info->key_ids[i]); } + av_encryption_init_info_free(info->next); av_free(info->system_id); av_free(info->key_ids); av_free(info->data); @@ -225,71 +229,111 @@ void av_encryption_init_info_free(AVEncryptionInitInfo *info) AVEncryptionInitInfo *av_encryption_init_info_get_side_data( const uint8_t *side_data, size_t side_data_size) { - AVEncryptionInitInfo *info; - uint64_t system_id_size, num_key_ids, key_id_size, data_size, i; + // |ret| tracks the front of the list, |info| tracks the back. + AVEncryptionInitInfo *ret = NULL, *info, *temp_info; + uint64_t system_id_size, num_key_ids, key_id_size, data_size, i, j; + uint64_t init_info_count; - if (!side_data || side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA) + if (!side_data || side_data_size < 4) return NULL; - system_id_size = AV_RB32(side_data); - num_key_ids = AV_RB32(side_data + 4); - key_id_size = AV_RB32(side_data + 8); - data_size = AV_RB32(side_data + 12); + init_info_count = AV_RB32(side_data); + side_data += 4; + side_data_size -= 4; + for (i = 0; i < init_info_count; i++) { + if (side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA) { + av_encryption_init_info_free(ret); + return NULL; + } - // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX - if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size) - return NULL; + system_id_size = AV_RB32(side_data); + num_key_ids = AV_RB32(side_data + 4); + key_id_size = AV_RB32(side_data + 8); + data_size = AV_RB32(side_data + 12); - info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size); - if (!info) - return NULL; + // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX + if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size) { + av_encryption_init_info_free(ret); + return NULL; + } + side_data += FF_ENCRYPTION_INIT_INFO_EXTRA; + side_data_size -= FF_ENCRYPTION_INIT_INFO_EXTRA; + + temp_info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size); + if (!temp_info) { + av_encryption_init_info_free(ret); + return NULL; + } + if (i == 0) { + info = ret = temp_info; + } else { + info->next = temp_info; + info = temp_info; + } - memcpy(info->system_id, side_data + 16, system_id_size); - side_data += system_id_size + 16; - for (i = 0; i < num_key_ids; i++) { - memcpy(info->key_ids[i], side_data, key_id_size); - side_data += key_id_size; + memcpy(info->system_id, side_data, system_id_size); + side_data += system_id_size; + side_data_size -= system_id_size; + for (j = 0; j < num_key_ids; j++) { + memcpy(info->key_ids[j], side_data, key_id_size); + side_data += key_id_size; + side_data_size -= key_id_size; + } + memcpy(info->data, side_data, data_size); + side_data += data_size; + side_data_size -= data_size; } - memcpy(info->data, side_data, data_size); - return info; + return ret; } uint8_t *av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size) { + const AVEncryptionInitInfo *cur_info; uint8_t *buffer, *cur_buffer; - uint32_t i, max_size; - - if (UINT32_MAX - FF_ENCRYPTION_INIT_INFO_EXTRA < info->system_id_size || - UINT32_MAX - FF_ENCRYPTION_INIT_INFO_EXTRA - info->system_id_size < info->data_size) { - return NULL; - } - - if (info->num_key_ids) { - max_size = UINT32_MAX - FF_ENCRYPTION_INIT_INFO_EXTRA - info->system_id_size - info->data_size; - if (max_size / info->num_key_ids < info->key_id_size) + uint32_t i, init_info_count; + uint64_t temp_side_data_size; + + temp_side_data_size = 4; + init_info_count = 0; + for (cur_info = info; cur_info; cur_info = cur_info->next) { + temp_side_data_size += (uint64_t)FF_ENCRYPTION_INIT_INFO_EXTRA + info->system_id_size + info->data_size; + if (init_info_count == UINT32_MAX || temp_side_data_size > UINT32_MAX) { return NULL; + } + init_info_count++; + + if (info->num_key_ids) { + temp_side_data_size += (uint64_t)info->num_key_ids * info->key_id_size; + if (temp_side_data_size > UINT32_MAX) { + return NULL; + } + } } + *side_data_size = temp_side_data_size; - *side_data_size = FF_ENCRYPTION_INIT_INFO_EXTRA + info->system_id_size + - info->data_size + (info->num_key_ids * info->key_id_size); cur_buffer = buffer = av_malloc(*side_data_size); if (!buffer) return NULL; - AV_WB32(cur_buffer, info->system_id_size); - AV_WB32(cur_buffer + 4, info->num_key_ids); - AV_WB32(cur_buffer + 8, info->key_id_size); - AV_WB32(cur_buffer + 12, info->data_size); - cur_buffer += 16; - - memcpy(cur_buffer, info->system_id, info->system_id_size); - cur_buffer += info->system_id_size; - for (i = 0; i < info->num_key_ids; i++) { - memcpy(cur_buffer, info->key_ids[i], info->key_id_size); - cur_buffer += info->key_id_size; + AV_WB32(cur_buffer, init_info_count); + cur_buffer += 4; + for (cur_info = info; cur_info; cur_info = cur_info->next) { + AV_WB32(cur_buffer, cur_info->system_id_size); + AV_WB32(cur_buffer + 4, cur_info->num_key_ids); + AV_WB32(cur_buffer + 8, cur_info->key_id_size); + AV_WB32(cur_buffer + 12, cur_info->data_size); + cur_buffer += 16; + + memcpy(cur_buffer, cur_info->system_id, cur_info->system_id_size); + cur_buffer += cur_info->system_id_size; + for (i = 0; i < cur_info->num_key_ids; i++) { + memcpy(cur_buffer, cur_info->key_ids[i], cur_info->key_id_size); + cur_buffer += cur_info->key_id_size; + } + memcpy(cur_buffer, cur_info->data, cur_info->data_size); + cur_buffer += cur_info->data_size; } - memcpy(cur_buffer, info->data, info->data_size); return buffer; } diff --git a/libavutil/encryption_info.h b/libavutil/encryption_info.h index ec5501aac7..9140968fde 100644 --- a/libavutil/encryption_info.h +++ b/libavutil/encryption_info.h @@ -115,6 +115,11 @@ typedef struct AVEncryptionInitInfo { */ uint8_t* data; uint32_t data_size; + + /** + * An optional pointer to the next initialization info in the list. + */ + struct AVEncryptionInitInfo *next; } AVEncryptionInitInfo; /** -- 2.18.0.rc2.346.g013aa6912e-goog