1db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root/* 2db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Copyright 2013 The Android Open Source Project 3db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 4db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Redistribution and use in source and binary forms, with or without 5db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * modification, are permitted provided that the following conditions are met: 6db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * * Redistributions of source code must retain the above copyright 7db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * notice, this list of conditions and the following disclaimer. 8db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * * Redistributions in binary form must reproduce the above copyright 9db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * notice, this list of conditions and the following disclaimer in the 10db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * documentation and/or other materials provided with the distribution. 11db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * * Neither the name of Google Inc. nor the names of its contributors may 12db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * be used to endorse or promote products derived from this software 13db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * without specific prior written permission. 14db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 15db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR 16db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 26db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 27db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root#include <string.h> 28db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 29f03f8485e7d1a5258e16e0e376229f431d2c53acMark Salyzyn#include "mincrypt/dsa_sig.h" 30db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root#include "mincrypt/p256.h" 31db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 32db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root/** 33db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Trims off the leading zero bytes and copy it to a buffer aligning it to the end. 34db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 35db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Rootstatic inline int trim_to_p256_bytes(unsigned char dst[P256_NBYTES], unsigned char *src, 36db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root int src_len) { 37db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root int dst_offset; 38db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root while (*src == '\0' && src_len > 0) { 39db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root src++; 40db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root src_len--; 41db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root } 42db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root if (src_len > P256_NBYTES || src_len < 1) { 43db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 0; 44db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root } 45db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root dst_offset = P256_NBYTES - src_len; 46db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root memset(dst, 0, dst_offset); 47db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root memcpy(dst + dst_offset, src, src_len); 48db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 1; 49db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root} 50db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 51db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root/** 52db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Unpacks the ASN.1 DSA signature sequence. 53db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 54db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Rootint dsa_sig_unpack(unsigned char* sig, int sig_len, p256_int* r_int, p256_int* s_int) { 55db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root /* 56db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Structure is: 57db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 0x30 0xNN SEQUENCE + s_length 58db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 0x02 0xNN INTEGER + r_length 59db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 0xAA 0xBB .. r_length bytes of "r" (offset 4) 60db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 0x02 0xNN INTEGER + s_length 61db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 0xMM 0xNN .. s_length bytes of "s" (offset 6 + r_len) 62db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 63db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root int seq_len; 64db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root unsigned char r_bytes[P256_NBYTES]; 65db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root unsigned char s_bytes[P256_NBYTES]; 66db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root int r_len; 67db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root int s_len; 68db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 69db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root memset(r_bytes, 0, sizeof(r_bytes)); 70db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root memset(s_bytes, 0, sizeof(s_bytes)); 71db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 72db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root /* 73db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Must have at least: 74db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 2 bytes sequence header and length 75db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 2 bytes R integer header and length 76db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 1 byte of R 77db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 2 bytes S integer header and length 78db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 1 byte of S 79db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 80db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 8 bytes total 81db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 82db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root if (sig_len < 8 || sig[0] != 0x30 || sig[2] != 0x02) { 83db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 0; 84db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root } 85db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 86db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root seq_len = sig[1]; 87db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root if ((seq_len <= 0) || (seq_len + 2 != sig_len)) { 88db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 0; 89db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root } 90db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 91db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root r_len = sig[3]; 92db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root /* 93db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Must have at least: 94db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 2 bytes for R header and length 95db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 2 bytes S integer header and length 96db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 1 byte of S 97db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 98db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root if ((r_len < 1) || (r_len > seq_len - 5) || (sig[4 + r_len] != 0x02)) { 99db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 0; 100db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root } 101db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root s_len = sig[5 + r_len]; 102db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 103db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root /** 104db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * Must have: 105db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 2 bytes for R header and length 106db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * r_len bytes for R 107db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * 2 bytes S integer header and length 108db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 109db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root if ((s_len < 1) || (s_len != seq_len - 4 - r_len)) { 110db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 0; 111db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root } 112db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 113db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root /* 114db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * ASN.1 encoded integers are zero-padded for positive integers. Make sure we have 115db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root * a correctly-sized buffer and that the resulting integer isn't too large. 116db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root */ 117db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root if (!trim_to_p256_bytes(r_bytes, &sig[4], r_len) 118db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root || !trim_to_p256_bytes(s_bytes, &sig[6 + r_len], s_len)) { 119db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 0; 120db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root } 121db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 122db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root p256_from_bin(r_bytes, r_int); 123db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root p256_from_bin(s_bytes, s_int); 124db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root 125db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root return 1; 126db0850c3b637faaa7cbe1bab2e6c91ad2af35426Kenny Root} 127