aes128gcm: why verify padding?

"Manger, James" <> Sun, 15 January 2017 23:56 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 96B561289B0 for <>; Sun, 15 Jan 2017 15:56:24 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -8.22
X-Spam-Status: No, score=-8.22 tagged_above=-999 required=5 tests=[BAYES_20=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-3.199, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (1024-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id LnXzmZkcVL6y for <>; Sun, 15 Jan 2017 15:56:22 -0800 (PST)
Received: from ( []) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 17EA7129509 for <>; Sun, 15 Jan 2017 15:56:21 -0800 (PST)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1cSuaY-0007mS-GQ for; Sun, 15 Jan 2017 23:51:54 +0000
Resent-Date: Sun, 15 Jan 2017 23:51:54 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1cSuaS-0007lg-QR for; Sun, 15 Jan 2017 23:51:48 +0000
Received: from ([]) by with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <>) id 1cSuaL-0003FM-2y for; Sun, 15 Jan 2017 23:51:43 +0000
X-IronPort-AV: E=Sophos;i="5.33,236,1477918800"; d="scan'208,217";a="132206121"
Received: from unknown (HELO ([]) by with ESMTP; 16 Jan 2017 10:51:07 +1100
X-IronPort-AV: E=McAfee;i="5700,7163,8409"; a="378728682"
Received: from ([]) by with ESMTP; 16 Jan 2017 10:51:07 +1100
Received: from ( by ( with Microsoft SMTP Server (TLS) id 8.3.485.1; Mon, 16 Jan 2017 10:51:07 +1100
Received: from ( by ( with Microsoft SMTP Server (TLS) id 15.0.1236.3; Mon, 16 Jan 2017 10:51:06 +1100
Received: from ( by ( with Microsoft SMTP Server (TLS) id 15.0.1236.3 via Frontend Transport; Mon, 16 Jan 2017 10:51:06 +1100
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=selector1-team-telstra-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=PoT3yK1LEOCGFQYOi2OLZdT1tYufmyKzh1eKl+7f5rY=; b=tDWBIQID6x20G7bRTMuZ05jYGZZnXjkpqKZU1/TFGmMbURwS2aZWGp9ZX01v9Ns9wSvfIhbJwUpG0NANSWPTq39Ytdfvv7fg/UxjVYXfh7sotDlBCjnZtGH8fiChD4Sm7eZzaz8aQzrNdyvl6M7E6cu2mUtTffIQ20MSLF29ZIU=
Received: from ( by ( with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Sun, 15 Jan 2017 23:51:05 +0000
Received: from ([]) by ([]) with mapi id 15.01.0845.013; Sun, 15 Jan 2017 23:51:05 +0000
From: "Manger, James" <>
To: "" <>
Thread-Topic: aes128gcm: why verify padding?
Thread-Index: AdJvg9D1nChV1RXVTGiVAO+6sRrzlw==
Date: Sun, 15 Jan 2017 23:51:05 +0000
Message-ID: <>
Accept-Language: en-AU, en-US
Content-Language: en-US
authentication-results: spf=none (sender IP is );
x-originating-ip: []
x-ms-office365-filtering-correlation-id: 0b1b5f91-9aa8-4028-10a3-08d43da15e91
x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:SYXPR01MB1616;
x-microsoft-exchange-diagnostics: 1; SYXPR01MB1616; 7:EsFCcvn9qY2ZeCdR/3UXJ9cOvJLtIvKXUPHYqqQtAIg1YFne+uuwzq70fMOwwhEQtTSoPWBUX9mPq3rHl867ILb4Jz6Y7yfCJLa5iBukVZh4co5nf8rnhXulrj5hKUjI+oeFcGevBUNc++coWzTYJCCKa1c4nyLY6qzty96VQoC42Qo0JrEZ3jKDfSQOeNOhrBKp0WnzSZjufASY4+0TgA2kfX9Nq4zPMGIoGS/aQpGX+FtVDHLf5at4xi5Bg2ulrrmdwvGtryB9gYpbDwoU8XsGkszHiUoAlBzT1HpGCbLzH1/yZ2NPQ8pgyuR8RIxREZgtLQtSQh6V+9qOyQL8BvgeHaNjI256q+qDmYyH2ebwVvDqU4dEHI3XWhN3GZgmStZ9W162jNlsUp+D+RSi8B8gac6fiWTKgfz8PuwKyqMqOV9JSGc9qibYOxV9X4xSSB+rciSXc/LUgXq1HpSdOA==
x-microsoft-antispam-prvs: <>
x-exchange-antispam-report-test: UriScan:(166708455590820)(192374486261705)(21748063052155);
x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040375)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148)(6042181); SRVR:SYXPR01MB1616; BCL:0; PCL:0; RULEID:; SRVR:SYXPR01MB1616;
x-forefront-prvs: 0188D66E61
x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(7916002)(189002)(199003)(790700001)(102836003)(50986999)(7110500001)(54356999)(110136003)(3846002)(189998001)(33656002)(2501003)(7696004)(2420400007)(15650500001)(97736004)(66066001)(6916009)(6116002)(42882006)(92566002)(5630700001)(8936002)(101416001)(2900100001)(27001)(2351001)(74316002)(9686003)(55016002)(5660300001)(3280700002)(99286003)(3660700001)(6306002)(54896002)(6506006)(10710500007)(8676002)(2906002)(25786008)(236005)(77096006)(6436002)(606005)(86362001)(38730400001)(450100001)(7736002)(122556002)(5640700003)(105586002)(68736007)(81156014)(107886002)(7906003)(81166006)(106356001); DIR:OUT; SFP:1102; SCL:1; SRVR:SYXPR01MB1616;; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:0; LANG:en;
received-spf: None ( does not designate permitted sender hosts)
spamdiagnosticoutput: 1:99
spamdiagnosticmetadata: NSPM
Content-Type: multipart/alternative; boundary="_000_SYXPR01MB161520224A59CDCE0D433A2CE57A0SYXPR01MB1615ausp_"
MIME-Version: 1.0
X-MS-Exchange-CrossTenant-originalarrivaltime: 15 Jan 2017 23:51:05.0846 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 49dfc6a3-5fb7-49f4-adea-c54e725bb854
X-MS-Exchange-Transport-CrossTenantHeadersStamped: SYXPR01MB1616
Received-SPF: none client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-2.1
X-W3C-Hub-Spam-Report: BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, W3C_NW=0.5
X-W3C-Scan-Sig: 1cSuaL-0003FM-2y 4e42b11c74f9dc7553ae5f02804f9b23
Subject: aes128gcm: why verify padding?
Archived-At: <>
X-Mailing-List: <> archive/latest/33283
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

draft-ietf-httpbis-encryption-encoding<> allows any amount of padding to be added alongside the content being encrypted. The spec says the receiver (decryptor) MUST confirm that every padding byte is 0x00. Why?

I'm not sure how it helps to check the padding. It doesn't make the encryption deterministic as there is a salt involved, and the length of padding can also vary. It isn't useful for integrity as that is provided by the GCM tag.

Checking the padding could be harmful. Padding (to a block size) has caused lots of security vulnerabilities when the padding is checked before doing a proper integrity check. AEAD algorithms (such as GCM) theoretically solve this, but only when receivers process a whole AEAD decryption in one go, not via a (very common) streaming API.

The aes128gcm Content-Encoding adds "app-layer" padding, but by putting it first with a fixed format it is almost tempting receivers to check it before processing the rest of the ciphertext, and hence introduce vulnerabilities.

3 possible improvements:

1.       Allow padding bytes to have any value. The receiver just skips them.

2.       Calculate the padding length by reducing a 2-byte unsigned integer modulo the maximum possible padding length (plaintext length - 2). That means every 2-byte value will give a valid padding length.

3.       Put the 2-byte padding length field at the end. So the receiver has to have a whole AEAD plaintext block before knowing where the content starts.

A plaintext block would be: plaintext = padding || content || padlen
Len(plaintext) is the record size - 16.
Len(padlen) is 2 bytes.
Len(padding) = padlen % (Len(plaintext) - 2)
Padding bytes have any value.
Content is the remainder of the plaintext block.

The nice feature of this is that every plaintext block is valid. The last 2 bytes can be anything; mod (Len(plaintext) - 2) always gives a valid padding length; padding can be anything; and all that is left is the content to pass to the next layer. With this arrangement there is very little risk that plaintext structure is dangerously checked before performing the AEAD integrity check.

This form is no harder that the current structure to process, but it does encourage proper use of AEAD APIs.

James Manger